De la documentación para la definición de into_clause
:la declaración SELECT INTO recupera una o más columnas de una sola fila y las almacena en una o más variables escalares o una variable de registro
Luego, la declaración SELECT actual debe reemplazarse en los casos de devolver más de una fila. Las siguientes consultas pueden ser alternativas para su instrucción SQL Select actual
SELECT reserve_id
INTO resid
FROM
( SELECT r.*,
ROW_NUMBER() OVER (ORDER BY 0) AS rn
FROM reservation
WHERE Cust_name = cname
AND Hotel_id = hotelID
AND reserve_date = resdate
)
WHERE rn = 1;
Si la versión DB es 12+, entonces use
SELECT reserve_id
INTO resid
FROM reservation
WHERE Cust_name = cname
AND Hotel_id = hotelID
AND reserve_date = resdate
FETCH NEXT 1 ROW ONLY;
sin una subconsulta para devolver solo una fila, considerando que solo obtiene duplicados para esas columnas sin reglas de orden para los datos. Mediante el uso de estas consultas, no es necesario manejar no_data_found
o too_many_rows
excepciones.
Actualización: Si su objetivo es devolver todas las filas, incluso si hay más de una fila a la vez, puede usar SYS_REFCURSOR
como
CREATE OR REPLACE FUNCTION findres(cname reservation.cust_name%type,
hotelID reservation.hotel_id%type,
resdate reservation.reserve_date%type)
RETURN SYS_REFCURSOR IS
recordset SYS_REFCURSOR;
BEGIN
OPEN recordset FOR
SELECT reserve_id
FROM reservation
WHERE Cust_name = cname
AND Hotel_id = hotelID
AND reserve_date = resdate;
RETURN recordset;
END;
/
y llamar de tal manera que
VAR v_rc REFCURSOR
EXEC :v_rc := findres('Avoras',111,date'2020-12-06');
PRINT v_rc
desde la consola del desarrollador de SQL.