Från dokumentationen för definition av into_clause
:SELECT INTO-satsen hämtar en eller flera kolumner från en enda rad och lagrar dem i antingen en eller flera skalära variabler eller en postvariabel
Då ska den aktuella SELECT-satsen ersättas mot fall av returnering av mer än en rad. Följande frågor kan vara alternativ för din nuvarande SQL Select-sats
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;
Om DB-versionen är 12+, använd sedan
SELECT reserve_id
INTO resid
FROM reservation
WHERE Cust_name = cname
AND Hotel_id = hotelID
AND reserve_date = resdate
FETCH NEXT 1 ROW ONLY;
utan en underfråga för att endast returnera en rad, med tanke på att du bara får dubbletter för de kolumner utan ordningsregler för data. Genom att använda dessa frågor behöver du inte hantera no_data_found
eller too_many_rows
undantag.
Uppdatering: Om ditt mål är att returnera alla rader även om det finns fler än en rad samtidigt, kan du använda SYS_REFCURSOR
som
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;
/
och ring på ett sådant sätt att
VAR v_rc REFCURSOR
EXEC :v_rc := findres('Avoras',111,date'2020-12-06');
PRINT v_rc
från SQL-utvecklarens konsol.