into_clause
の定義に関するドキュメントから : SELECT INTOステートメントは、単一の行から1つ以上の列を取得し、それらを1つ以上のスカラー変数または1つのレコード変数に格納します
次に、現在のSELECTステートメントを、複数の行を返す場合に置き換える必要があります。次のクエリは、現在のSQLSelectステートメントの代替となる可能性があります
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;
データの順序付けルールがない列の重複のみを取得することを考慮して、1行のみを返すためのサブクエリなし。これらのクエリを使用することで、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
SQLDeveloperのコンソールから。