Plsql-cursors

提供:Dev Guides
移動先:案内検索

PL/SQL-カーソル

この章では、PL/SQLのカーソルについて説明します。 Oracleは、SQL文を処理するためのコンテキスト領域と呼ばれるメモリ領域を作成します。SQL領域には、文の処理に必要なすべての情報が含まれます。たとえば、処理された行の数など。

  • カーソル*は、このコンテキスト領域へのポインタです。 PL/SQLは、カーソルを介してコンテキスト領域を制御します。 カーソルは、SQLステートメントによって返された行(1つ以上)を保持します。 カーソルが保持する行のセットは、*アクティブセット*と呼ばれます。

カーソルに名前を付けると、プログラムで参照できるようになり、SQLステートメントによって返される行を一度に1つずつフェッチして処理できます。 カーソルには2種類あります-

  • 暗黙カーソル
  • 明示カーソル

暗黙カーソル

暗黙カーソルは、SQL文が実行されるたびに、文に明示的なカーソルがない場合、Oracleによって自動的に作成されます。 プログラマは、暗黙カーソルとその中の情報を制御できません。

DMLステートメント(INSERT、UPDATE、DELETE)が発行されるたびに、暗黙的なカーソルがこのステートメントに関連付けられます。 INSERT操作の場合、カーソルは挿入する必要のあるデータを保持します。 UPDATEおよびDELETE操作の場合、カーソルは影響を受ける行を識別します。

PL/SQLでは、最新の暗黙カーソルを* SQLカーソル*として参照できます。* SQLカーソル*には、常に*%FOUND、%ISOPEN、%NOTFOUND および%ROWCOUNT などの属性があります。 SQLカーソルには、 *FORALL ステートメントで使用するために設計された追加の属性*%BULK_ROWCOUNT および%BULK_EXCEPTIONS *があります。 次の表は、最も使用される属性の説明を提供します-

S.No Attribute & Description
1

%FOUND

INSERT、UPDATE、またはDELETEステートメントが1つ以上の行に影響した場合、またはSELECT INTOステートメントが1つ以上の行を返した場合、TRUEを返します。 それ以外の場合は、FALSEを返します。

2

%NOTFOUND

%FOUNDの論理的な反対。 INSERT、UPDATE、またはDELETEステートメントが行に影響しない場合、またはSELECT INTOステートメントが行を返さない場合、TRUEを返します。 それ以外の場合は、FALSEを返します。

3

%ISOPEN

暗黙カーソルの場合は常にFALSEが返されます。これは、関連するSQL文の実行後にOracleがSQLカーソルを自動的に閉じるためです。

4

%ROWCOUNT

INSERT、UPDATE、またはDELETEステートメントによって影響を受けた行、またはSELECT INTOステートメントによって返された行の数を返します。

以下の例に示すように、SQLカーソル属性はすべて sql%attribute_name としてアクセスされます。

前の章で作成して使用したCUSTOMERSテーブルを使用します。

Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
+----+----------+-----+-----------+----------+

次のプログラムは、テーブルを更新し、各顧客の給与を500増やし、 SQL%ROWCOUNT 属性を使用して、影響を受ける行の数を決定します-

DECLARE
   total_rows number(2);
BEGIN
   UPDATE customers
   SET salary = salary + 500;
   IF sql%notfound THEN
      dbms_output.put_line('no customers selected');
   ELSIF sql%found THEN
      total_rows := sql%rowcount;
      dbms_output.put_line( total_rows || ' customers selected ');
   END IF;
END;
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

6 customers selected

PL/SQL procedure successfully completed.

顧客テーブルのレコードを確認すると、行が更新されていることがわかります-

Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2500.00 |
|  2 | Khilan   |  25 | Delhi     |  2000.00 |
|  3 | kaushik  |  23 | Kota      |  2500.00 |
|  4 | Chaitali |  25 | Mumbai    |  7000.00 |
|  5 | Hardik   |  27 | Bhopal    |  9000.00 |
|  6 | Komal    |  22 | MP        |  5000.00 |
+----+----------+-----+-----------+----------+

明示カーソル

明示カーソルは、*コンテキスト領域*をより詳細に制御するためのプログラマ定義のカーソルです。 PL/SQLブロックの宣言セクションで明示カーソルを定義する必要があります。 複数の行を返すSELECTステートメントで作成されます。

明示カーソルを作成するための構文は次のとおりです-

CURSOR cursor_name IS select_statement;

明示カーソルの操作には、次の手順が含まれます-

  • メモリを初期化するためのカーソルを宣言する
  • メモリを割り当てるためにカーソルを開く
  • データを取得するためのカーソルの取得
  • カーソルを閉じて、割り当てられたメモリを解放する

カーソルの宣言

カーソルを宣言すると、名前と関連付けられたSELECTステートメントでカーソルが定義されます。 たとえば-

CURSOR c_customers IS
   SELECT id, name, address FROM customers;

カーソルを開く

カーソルを開くと、カーソルのメモリが割り当てられ、SQLステートメントによって返された行をフェッチする準備が整います。 たとえば、次のように上記で定義したカーソルを開きます-

OPEN c_customers;

カーソルの取得

カーソルをフェッチするには、一度に1行ずつアクセスする必要があります。 たとえば、次のように上で開いたカーソルから行をフェッチします-

FETCH c_customers INTO c_id, c_name, c_addr;

カーソルを閉じる

カーソルを閉じるとは、割り当てられたメモリを解放することを意味します。 たとえば、次のように上で開いたカーソルを閉じます-

CLOSE c_customers;

以下は、明示カーソルの概念を説明する完全な例です&minua;

DECLARE
   c_id customers.id%type;
   c_name customer.name%type;
   c_addr customers.address%type;
   CURSOR c_customers is
      SELECT id, name, address FROM customers;
BEGIN
   OPEN c_customers;
   LOOP
   FETCH c_customers into c_id, c_name, c_addr;
      EXIT WHEN c_customers%notfound;
      dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr);
   END LOOP;
   CLOSE c_customers;
END;
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

1 Ramesh Ahmedabad
2 Khilan Delhi
3 kaushik Kota
4 Chaitali Mumbai
5 Hardik Bhopal
6 Komal MP

PL/SQL procedure successfully completed.