От документацията за дефиниране на into_clause
:операторът SELECT INTO извлича една или повече колони от един ред и ги съхранява в една или повече скаларни променливи или в една записваща променлива
Тогава текущият оператор SELECT трябва да бъде заменен срещу случаите на връщане на повече от един ред. Следните заявки може да са алтернативи за текущия ви оператор за SQL Select
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;
Ако версията на DB е 12+, използвайте
SELECT reserve_id
INTO resid
FROM reservation
WHERE Cust_name = cname
AND Hotel_id = hotelID
AND reserve_date = resdate
FETCH NEXT 1 ROW ONLY;
без подзаявка, за да върне само един ред, като се има предвид, че получавате само дубликати за тези колони без правила за подреждане на данните. Чрез използването на тези заявки няма нужда да обработвате no_data_found
или too_many_rows
изключения.
Актуализация: Ако целта ви е да върнете всички редове, дори да има повече от един ред наведнъж, тогава можете да използвате SYS_REFCURSOR
като например
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;
/
и се обадете по такъв начин, че
VAR v_rc REFCURSOR
EXEC :v_rc := findres('Avoras',111,date'2020-12-06');
PRINT v_rc
от конзолата на SQL Developer.