PLは、より使いやすいFORループステートメントを提供しており、カーソルのOPEN、FETCH、CLOSEステートメントとループステートメントの機能を自動的に実行します。
適用対象
この内容はOceanBaseデータベースEnterprise Editionにのみ適用されます。OceanBaseデータベースCommunity EditionはMySQLモードのみを提供します。
ループに入ると、カーソルFORループステートメントは自動的にカーソルを開き、最初の行のカーソルデータを取得します。プログラムが現在取得したデータの処理を終えて次のループに進むと、カーソルFORループステートメントは自動的に次の行のデータを取得してプログラムで処理します。結果セット内のすべてのデータ行を取得した後、ループを終了し、カーソルを自動的に閉じます。
書式は以下のとおりです:
FOR index_variable IN cursor_name[value[, value]...] LOOP
-- カーソルデータ処理コード
END LOOP;
index_variableはカーソルFORループステートメントによって暗黙的に宣言されたインデックス変数であり、DECLAREで宣言する必要はありません。この変数はRECORD型であり、その構造はカーソルクエリステートメントが返す構造集合と同じです。
プログラムでは、このインデックスレコード変数の要素を参照することで、取得したカーソルデータを読み取ることができます。index_variableの各要素の名前は、カーソルクエリステートメントの選択リストで指定された列名と同じです。カーソルクエリステートメントの選択リストに計算列が存在する場合、これらの計算列にはエイリアスを指定してから、カーソルFORループステートメント内のインデックス変数を使用してこれらの列データにアクセスする必要があります。
例:
obclient> CREATE TABLE emp(
empno NUMBER(4,0),
empname VARCHAR(10),
job VARCHAR(10),
deptno NUMBER(2,0),
salary NUMERIC
);
Query OK, 0 rows affected
obclient> INSERT INTO emp VALUES (200,'Jennifer','AD_ASST',1,15000),(202,'Pat','MK_REP',2,12000),
(119,'Karen','PU_CLERK', 4,10000),(118,'Guy','PU_CLERK', 4,10000),
(201,'Michael','MK_MAN',3,9000);
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
obclient> DECLARE
CURSOR c_emp IS SELECT empname, salary
FROM emp where rownum<5;
BEGIN
--暗黙的にカーソルを開く
FOR r_emp IN c_emp LOOP
--暗黙的にFETCHステートメントを実行する
DBMS_OUTPUT.PUT_LINE(r_emp.empname||'''s salary is '||r_emp.salary );
--暗黙的にc_emp%NOTFOUNDを検出する
END LOOP;
END;
/
Query OK, 0 rows affected
Jennifer's salary is 15000
Pat's salary is 12000
Karen's salary is 10000
Guy's salary is 10000
FORを使用してカーソルをイテレーションする際にも、カーソルパラメータを渡すことができます。例:
obclient> DECLARE
CURSOR c_emp (in_job varchar default 'AC_MGR' ) IS
SELECT empname, salary
FROM emp where job = in_job;
v_job emp.job%TYPE;
BEGIN
v_job := 'PU_CLERK';
FOR r_emp IN c_emp(v_job) LOOP
DBMS_OUTPUT.PUT_LINE('DEPT '||v_job||': '||r_emp.empname||'''s salary is '||r_emp.salary );
END LOOP;
END;
/
Query OK, 0 rows affected
DEPT PU_CLERK: Karen's salary is 10000
DEPT PU_CLERK: Guy's salary is 10000
PLはまた、FORループ内でサブクエリを使用してカーソルを直接定義することも許可しています。例:
obclient> BEGIN
FOR r_emp IN (SELECT empname, salary FROM emp) LOOP
DBMS_OUTPUT.PUT_LINE(r_emp.empname||'''s salary is '||r_emp.salary );
END LOOP;
END;
/
Query OK, 0 rows affected
Jennifer's salary is 15000
Pat's salary is 12000
Karen's salary is 10000
Guy's salary is 10000
Michael's salary is 9000