You can use the Oracle pipelined function functionality:
Step 1: Create an object the represents one row of the results:
CREATE OR REPLACE TYPE city_type
AS OBJECT
(
city_id VARCHAR(6),
city_name VARCHAR(60)
);
Step 2: Create a collection (table type) of the object type created in step 1
CREATE OR REPLACE TYPE city_table_type
AS TABLE OF city_type;
Step 3: Create a function that returns the table type from step 3
CREATE OR REPLACE FUNCTION fnc_Get_Cities_Pipelined
RETURN city_table_type
PIPELINED
AS
BEGIN
FOR v_Rec IN (SELECT * FROM city) LOOP
PIPE ROW (city_type(v_Rec.City_Id, v_Rec.City_Name));
END LOOP;
RETURN;
END;
Step 4: Consume the function as if it was a “table” or “view”
SELECT city_id, city_name
FROM TABLE(fnc_Get_Cities_Pipelined());