【PL/SQL】カーソルでSQLクエリで取得した複数の行を1行ずつ処理する方法

PL/SQLにおけるカーソルは、データベースから複数行の結果を取得して操作するために使用される重要な構造です。本記事では、PL/SQLのカーソルについて基本的な概念から使用方法までを詳しく解説します。

カーソルとは?

カーソルは、SQL文の実行結果である複数の行を順次処理するためのデータ構造です。通常のSQL文では単一の結果を取得しますが、カーソルを使用することで複数行を1行ずつ処理できます。

暗黙的カーソル

暗黙的カーソルは、PL/SQLでSQL文が実行された際にOracleが自動的に作成・管理します。特別な処理を行わずに1行の結果を簡単に取得できます。

DECLARE
    emp_name employees.first_name%TYPE;
BEGIN
    SELECT first_name INTO emp_name
    FROM employees
    WHERE employee_id = 101;

    DBMS_OUTPUT.PUT_LINE('Employee Name: ' || emp_name);
END;
/

この例では、SELECT INTO文を使用してemployeesテーブルから特定の従業員の名前を取得しています。カーソル操作はOracleが自動的に行います。

明示的カーソル

明示的カーソルは、複数の行を手動で管理する必要がある場合に使用します。カーソルを宣言し、開き、フェッチし、閉じるといった操作を行い、データを順次処理できます。

DECLARE
    CURSOR emp_cursor IS
        SELECT first_name, last_name FROM employees;
    emp_first employees.first_name%TYPE;
    emp_last employees.last_name%TYPE;
BEGIN
    OPEN emp_cursor;
    LOOP
        FETCH emp_cursor INTO emp_first, emp_last;
        EXIT WHEN emp_cursor%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('Employee: ' || emp_first || ' ' || emp_last);
    END LOOP;
    CLOSE emp_cursor;
END;
/

この例では、カーソルemp_cursorを使用して従業員の名前を1行ずつ処理し、出力しています。

カーソル属性

カーソルには、現在の状態を確認できる属性が用意されています。これにより、カーソルが正常に動作しているかどうかや、フェッチした行数を確認することができます。

  • %FOUND: データがフェッチされたかどうかを確認
  • %NOTFOUND: データが存在しなかったかどうかを確認
  • %ROWCOUNT: フェッチされた行数を確認
  • %ISOPEN: カーソルが開いているかどうかを確認
DECLARE
    CURSOR emp_cursor IS
        SELECT first_name FROM employees;
    emp_name employees.first_name%TYPE;
BEGIN
    OPEN emp_cursor;
    LOOP
        FETCH emp_cursor INTO emp_name;
        EXIT WHEN emp_cursor%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('Employee: ' || emp_name);
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('Total rows fetched: ' || emp_cursor%ROWCOUNT);
    CLOSE emp_cursor;
END;
/

この例では、カーソルemp_cursorの%ROWCOUNT属性を使って、フェッチされた行数を出力しています。

パラメータ付きカーソル

カーソルはパラメータを持つこともでき、これによりクエリに動的な入力を渡して実行することが可能です。

DECLARE
    CURSOR emp_cursor (dept_id NUMBER) IS
        SELECT first_name, last_name FROM employees WHERE department_id = dept_id;
    emp_first employees.first_name%TYPE;
    emp_last employees.last_name%TYPE;
BEGIN
    OPEN emp_cursor(10);
    LOOP
        FETCH emp_cursor INTO emp_first, emp_last;
        EXIT WHEN emp_cursor%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('Employee: ' || emp_first || ' ' || emp_last);
    END LOOP;
    CLOSE emp_cursor;
END;
/

この例では、パラメータとして部門IDを受け取り、その部門に所属する従業員を取得しています。

まとめ

PL/SQLのカーソルは、複数行の結果セットを効率的に処理するための強力なツールです。暗黙的カーソルと明示的カーソルを使い分け、必要に応じてパラメータを活用することで、柔軟なデータ処理が可能となります。