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 の各要素名は、カーソルクエリステートメントのSELECTリストで指定された列名と同じです。カーソルクエリステートメントのSELECTリストに計算列が含まれる場合は、これらの計算列にエイリアスを指定しておく必要があります。そうすることで、カーソル 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