Oracle PL/SQL カーソル: 暗黙的、明示的、For ループと例
PL/SQLのCURSORとは何ですか?
カーソルは、このコンテキスト領域へのポインタです。 Oracle SQL ステートメントを処理するためのコンテキスト領域を作成します。この領域にはステートメントに関するすべての情報が含まれます。
PL/SQL を使用すると、プログラマはカーソルを介してコンテキスト領域を制御できます。 カーソルは、SQL ステートメントによって返された行を保持します。 カーソルが保持する行のセットは、アクティブ セットと呼ばれます。 これらのカーソルには、コードの別の場所から参照できるように名前を付けることもできます。
カーソルには XNUMX つのタイプがあります。
- 暗黙カーソル
- 明示カーソル
暗黙カーソル
データベースで DML 操作が発生するたびに、その特定の操作で影響を受ける行を保持する暗黙的なカーソルが作成されます。これらのカーソルには名前を付けることができないため、コードの別の場所から制御または参照することはできません。カーソル属性を通じて参照できるのは、最新のカーソルのみです。
明示カーソル
プログラマーは、DML操作を実行するための名前付きコンテキスト領域を作成し、より詳細な制御を行うことができます。明示的なカーソルは、 PL/SQLブロック、コード内で使用する必要がある「SELECT」ステートメント用に作成されます。
以下に、明示カーソルの操作に関連する手順を示します。
- カーソルの宣言 カーソルの宣言は、単に宣言部分で定義された 'SELECT' ステートメントに対して XNUMX つの名前付きコンテキスト領域を作成することを意味します。 このコンテキスト領域の名前はカーソル名と同じです。
- オープニングカーソルカーソルを開くと、 PL / SQLの このカーソルにメモリを割り当てます。 これにより、カーソルがレコードをフェッチできる状態になります。
- カーソルからデータを取得するこのプロセスでは、「SELECT」ステートメントが実行され、フェッチされた行が割り当てられたメモリに格納されます。 これらは現在、アクティブ セットと呼ばれています。 カーソルからのデータのフェッチはレコードレベルのアクティビティであり、レコードごとにデータにアクセスできることを意味します。 各 fetch ステートメントは XNUMX つのアクティブ セットをフェッチし、その特定のレコードの情報を保持します。 このステートメントは、レコードをフェッチして 'INTO' 句の変数に代入する 'SELECT' ステートメントと同じですが、例外はスローされません。
- カーソルを閉じるすべてのレコードがフェッチされたら、カーソルを閉じて、このコンテキスト領域に割り当てられたメモリを解放する必要があります。
構文
DECLARE CURSOR <cursor_name> IS <SELECT statement^> <cursor_variable declaration> BEGIN OPEN <cursor_name>; FETCH <cursor_name> INTO <cursor_variable>; . . CLOSE <cursor_name>; END;
- 上記の構文では、宣言部分には、フェッチされたデータが代入されるカーソルとカーソル変数の宣言が含まれます。
- カーソルは、カーソル宣言で指定された 'SELECT' ステートメントに対して作成されます。
- 実行部分では、宣言されたカーソルがオープン、フェッチ、クローズされます。
カーソルの属性
暗黙カーソルと明示カーソルの両方に、アクセスできる特定の属性があります。これらの属性は、カーソル操作に関する詳細情報を提供します。以下は、さまざまなカーソル属性とその使用法です。
カーソル属性 | Description |
---|---|
%FOUND | 最新のフェッチ操作でレコードが正常にフェッチされた場合はブール値の結果「TRUE」を返し、それ以外の場合は FALSE を返します。 |
%見つかりません | これは %FOUND とは逆に動作し、最新のフェッチ操作でレコードをフェッチできなかった場合は 'TRUE' を返します。 |
%ISOPEN | 指定されたカーソルがすでに開かれている場合はブール結果「TRUE」を返し、それ以外の場合は「FALSE」を返します。 |
%ROWCOUNT | 数値を返します。 これは、DML アクティビティの影響を受けたレコードの実際の数を示します。 |
明示的なカーソルの例:
この例では、明示カーソルを宣言、オープン、フェッチ、クローズする方法を見ていきます。
カーソルを使用して、emp テーブルからすべての従業員の名前を投影します。 また、cursor 属性を使用して、カーソルからすべてのレコードをフェッチするループを設定します。
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; lv_emp_name emp.emp_name%type; BEGIN OPEN guru99_det; LOOP FETCH guru99_det INTO lv_emp_name; IF guru99_det%NOTFOUND THEN EXIT; END IF; Dbms_output.put_line(‘Employee Fetched:‘||lv_emp_name); END LOOP; Dbms_output.put_line(‘Total rows fetched is‘||guru99_det%R0WCOUNT); CLOSE guru99_det; END: /
出力
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY Total rows fetched is 3
コードの説明
- コード行 2: ステートメント「SELECT emp_name FROM emp」に対してカーソル guru99_det を宣言しています。
- コード行 3: 変数 lv_emp_name を宣言しています。
- コード行 5: カーソル guru99_det を開きます。
- コード行 6: 「emp」テーブル内のすべてのレコードをフェッチするように Basic ループ ステートメントを設定します。
- コード行 7: guru99_det データを取得し、その値を lv_emp_name に割り当てます。
- コード行 9: カーソル属性 '%NOTFOUND' を使用して、カーソル内のすべてのレコードがフェッチされたかどうかを確認します。 フェッチされた場合は「TRUE」を返し、コントロールはループを終了します。そうでない場合、コントロールはカーソルからデータをフェッチし続け、データを出力します。
- コード行 11: ループステートメントの EXIT 条件。
- コード行 12: 取得した従業員名を出力します。
- コード行 14: カーソル属性 '%ROWCOUNT' を使用して、カーソル内で影響を受けた/フェッチされたレコードの合計数を見つけます。
- コード行 15: ループを終了すると、カーソルが閉じられ、割り当てられたメモリが解放されます。
FOR ループ カーソル ステートメント
「FOR LOOP」ステートメントはカーソルの操作に使用できます。 FOR ループ ステートメントで範囲制限の代わりにカーソル名を指定すると、ループがカーソルの最初のレコードからカーソルの最後のレコードまで機能するようになります。 カーソル変数、カーソルのオープン、カーソルのフェッチとクローズは、FOR ループによって暗黙的に行われます。
構文
DECLARE CURSOR <cursor_name> IS <SELECT statement>; BEGIN FOR I IN <cursor_name> LOOP . . END LOOP; END;
- 上記の構文では、宣言部分にカーソルの宣言が含まれています。
- カーソルは、カーソル宣言で指定された 'SELECT' ステートメントに対して作成されます。
- 実行部では、宣言されたカーソルがFORループ内に設定されており、この場合ループ変数「I」がカーソル変数として動作します。
Oracle ループのカーソルの例:
この例では、カーソル FOR ループを使用して、emp テーブルからすべての従業員名を射影します。
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; BEGIN FOR lv_emp_name IN guru99_det LOOP Dbms_output.put_line(‘Employee Fetched:‘||lv_emp_name.emp_name); END LOOP; END; /
出力
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY
コードの説明
- コード行 2: ステートメント「SELECT emp_name FROM emp」に対してカーソル guru99_det を宣言しています。
- コード行 4: ループ変数 lv_emp_name を使用してカーソルの 'FOR' ループを構築します。
- コード行 5: ループの各反復で従業員名を出力します。
- コード行 8: ループを終了する
ご注意: Cursor-FOR ループでは、カーソルのオープン、フェッチ、クローズが暗黙的に実行されるため、カーソル属性は使用できません。 FOR ループ.