ストアドプロシージャを作成します。

構文

CREATE [OR REPLACE] PROCEDURE name [ (parameters) ]
   [
          IMMUTABLE
        | STABLE
        | VOLATILE
        | DETERMINISTIC
        | [ NOT ] LEAKPROOF
        | CALLED ON NULL INPUT
        | RETURNS NULL ON NULL INPUT
        | STRICT
        | [ EXTERNAL ] SECURITY INVOKER
        | [ EXTERNAL ] SECURITY DEFINER
        | AUTHID DEFINER
        | AUTHID CURRENT_USER
        | PARALLEL { UNSAFE | RESTRICTED | SAFE }
        | COST execution_cost
        | ROWS result_rows
        | SET configuration_parameter
          { TO value | = value | FROM CURRENT }
   ...]
{ IS | AS }
    [ PRAGMA AUTONOMOUS_TRANSACTION; ]
    [ declarations ]
  BEGIN
    statements
  END [ name ];

説明

CREATE PROCEDURE により、ストアドプロシージャが作成されます。 CREATE OR REPLACE PROCEDURE により、新しいストアドプロシージャが作成されるか、または既存の定義が置き換えられます。

スキーマ名を指定すると、ストアドプロシージャは指定したスキーマに作成されます。 それ以外の場合、ストアドプロシージャは現在のスキーマに作成されます。 新しいストアドプロシージャの名前は、同じスキーマにある同じ入力引数の型を持つ既存のストアドプロシージャと同じものにはできません。 ただし、異なる入力引数の型のストアドプロシージャであれば名前を共有できます。 これはオーバーロードと呼ばれています。 ストアドプロシージャのオーバーロードは、Oracle と互換性のある PolarDB データベースの機能です。 スタンドアロンストアドプロシージャのオーバーロードは、Oracle データベースと互換性がありません。

既存のストアドプロシージャの定義を更新するには、CREATE OR REPLACE PROCEDURE 文を使用します。 CREATE OR REPLACE PROCEDURE 文を使用して、ストアドプロシージャの名前や引数の型を変更することはできません。 試行した場合、新しい別のストアドプロシージャが作成されます。 OUT パラメーターを使用する場合は、ストアドプロシージャを削除しない限り、OUT パラメーターの型は変更できません。

パラメーター

パラメーター 説明
name ストアドプロシージャの識別子。
parameters パラメーター値のリスト。
declarations 変数、カーソル、型、またはサブプログラムの宣言。 サブプログラムの宣言が含まれている場合は、他の変数、カーソル、および型をすべて宣言した後にサブプログラムを宣言する必要があります。
statements SPL プログラム文。 BEGIN から END のブロックには、EXCEPTION セクションを含めることができます。
IMMUTABLE | STABLE | VOLATILE これらの属性は、ストアドプロシージャの動作についてクエリオプティマイザーに通知するために使用されます。 どれか 1 つのみ指定できます。 VOLATILE がデフォルトの動作です。
  • IMMUTABLE は、ストアドプロシージャでデータベースが変更されず、同じ引数値を指定している場合は常に同じ結果が返されることを示します。 ストアドプロシージャでは、データベース検索は実行されず、引数リストから除外されている情報は使用されません。 この句が含まれている場合、すべて定数引数を持つストアドプロシージャの呼び出しは、ストアドプロシージャの値ですぐに置き換えることができます。
  • STABLE は、ストアドプロシージャでデータベースが変更されず、ストアドプロシージャで、1 回のテーブルスキャン内で同じ引数値に対して同じ結果が返されることを示します。 この場合、SQL 文間で結果が変わることがあります。 この属性は、データベース検索や、現在のタイムゾーンなどのパラメーター変数に依存しているストアドプロシージャに適しています。
  • VOLATILE は、1 回のテーブルスキャン内でストアドプロシージャの値が変わることを示します。 この場合、最適化は行えません。 結果が予測可能であっても、悪影響を及ぼす関数は揮発性関数として分類する必要があることにご注意ください。 これにより、最適化により呼び出しが削除されるのを防ぎます。
DETERMINISTIC DETERMINISTIC は、IMMUTABLE と同義語です。 DETERMINISTIC ストアドプロシージャでは、データベースは変更されず、同じ引数値を指定している場合は常に同じ結果が返されます。 ストアドプロシージャでは、データベース検索は実行されず、引数リストから除外されている情報は使用されません。 この句が含まれている場合、すべて定数引数を持つストアドプロシージャの呼び出しは、ストアドプロシージャの値ですぐに置き換えることができます。
[ NOT ] LEAKPROOF LEAKPROOF ストアドプロシージャには、悪影響はなく、ストアドプロシージャの呼び出しに使用される値に関する情報は公開されません。
CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
  • CALLED ON NULL INPUT がデフォルト値です。 これは、一部の引数が NULL のときにストアドプロシージャが呼び出されることを示しています。 必要に応じて、作成者は NULL 値をチェックし、適切に応答する必要があります。
  • RETURNS NULL ON NULL INPUT または STRICT は、一部の引数が NULL の場合は常にストアドプロシージャで NULL が返されることを表しています。 これらの句を指定すると、NULL 引数が存在する場合、ストアドプロシージャは実行されません。 NULL の結果は自動的に返されます。
[ EXTERNAL ] SECURITY DEFINER SECURITY DEFINER は、ストアドプロシージャを作成したユーザーの特権でストアドプロシージャを実行することを指定します。 これがデフォルト値です。 EXTERNAL キーワードは、SQL に準拠するために許可されていますが、オプションです。
[ EXTERNAL ] SECURITY INVOKER SECURITY INVOKER 句は、ストアドプロシージャを呼び出すユーザーの特権でストアドプロシージャが実行されることを示します。 EXTERNAL キーワードは、SQL に準拠するために許可されていますが、オプションです。
AUTHID DEFINER | AUTHID CURRENT_USER
  • AUTHID DEFINER 句は、[EXTERNAL] SECURITY DEFINER のシノニムです。 AUTHID 句を省略した場合、または AUTHID DEFINER を指定した場合は、ストアドプロシージャの所有者の権限を使用して、データベースオブジェクトへのアクセス特権が決定されます。
  • AUTHID CURRENT_USER 句は、[EXTERNAL] SECURITY INVOKER のシノニムです。 AUTHID CURRENT_USER が指定されている場合、ストアドプロシージャを実行している現在のユーザーの権限を使用して、アクセス特権が決定されます。
PARALLEL { UNSAFE | RESTRICTED | SAFE } PARALLEL 句により、並列シーケンシャルスキャン (並列モード) の使用が有効になります。 並列シーケンシャルスキャンは、直列シーケンシャルスキャンとは対照的に、クエリ中に複数のワーカーを使用してリレーションを並列にスキャンします。
  • このパラメーターが UNSAFE に設定されていると、ストアドプロシージャは並列モードで実行できません。 このようなストアドプロシージャが SQL 文に存在する場合は、直列実行プランが実施されます。 PARALLEL 句を省略した場合は、これがデフォルト設定になります。
  • このパラメーターを RESTRICTED に設定した場合、ストアドプロシージャは並列モードで実行できますが、実行は並列グループリーダーに限定されます。 特定の関係に対する資格に、並列に制限されたコンテンツがある場合、その関係は並列実行用に選択されません。
  • このパラメーターを SAFE に設定した場合、ストアドプロシージャは、制限なく並列モードで実行できます。
COST execution_cost execution_cost は、ストアドプロシージャの推定実行コストを示す正の値です。 単位は cpu_operator_cost です。 ストアドプロシージャでセットが返される場合、これが、返された各行のコストになります。 値が大きいほど、プランナーによる必要以上に頻繁なストアドプロシージャの評価を防ぎます。
ROWS result_rows result_rows は、ストアドプロシージャが返すことをプランナーが期待する行の推定数を示す正の値です。 この値は、ストアドプロシージャでセットを返すように宣言されている場合にのみ使用できます。 デフォルト値は 1000 行です。
SET configuration_parameter { TO value | = value | FROM CURRENT } SET 句を使用すると、ストアドプロシージャに入るときに、指定した設定パラメーターが指定値に設定され、ストアドプロシージャが終了するときに、以前の値に復元されます。 SET FROM CURRENT により、ストアドプロシージャに入ったときにパラメーターの現在値が、適用される値として保存されます。

ストアドプロシージャに SET 句がアタッチされている場合、同じ変数に対してストアドプロシージャ内で実行された SET LOCAL コマンドの影響は、ストアドプロシージャに限定されます。 ストアドプロシージャが終了すると、設定パラメーターは以前の値に復元されます。 ストアドプロシージャが終了すると、設定パラメーターは以前の値に復元されます。 LOCAL を使用しない通常の SET コマンドは、SET 句をオーバーライドします。 これは、以前の SET LOCAL コマンドと同様です。 このようなコマンドの影響は、現在のトランザクションがロールバックされない限り、ストアドプロシージャの終了後も残ります。

PRAGMA AUTONOMOUS_TRANSACTION PRAGMA AUTONOMOUS_TRANSACTION は、ストアドプロシージャを自律型トランザクションとして設定するディレクティブです。
  • STRICT、LEAKPROOF、PARALLEL、COST、ROWS、SET の各キーワードは、Oracle と互換性のある PolarDB データベース用の拡張機能を提供します。 ただし、これらのキーワードは Oracle データベースではサポートされていません。
  • IMMUTABLE、STABLE、STRICT、LEAKPROOF、COST、ROWS、PARALLEL { UNSAFE | RESTRICTED | SAFE } の各属性は、Oracle と互換性のある PolarDB データベースのストアドプロシージャでのみ使用できます。
  • ストアドプロシージャは、デフォルトでは、SECURITY DEFINERS として作成されます。 plpgsql で定義されたストアドプロシージャは、SECURITY INVOKERS として作成されます。

次のストアドプロシージャは、emp テーブルの従業員の一覧です。

CREATE OR REPLACE PROCEDURE list_emp
IS
    v_empno         NUMBER(4);
    v_ename         VARCHAR2(10);
    CURSOR emp_cur IS
        SELECT empno, ename FROM emp ORDER BY empno;
BEGIN
    OPEN emp_cur;
    DBMS_OUTPUT.PUT_LINE('EMPNO    ENAME');
    DBMS_OUTPUT.PUT_LINE('-----    -------');
    LOOP
        FETCH emp_cur INTO v_empno, v_ename;
        EXIT WHEN emp_cur%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(v_empno || '     ' || v_ename);
    END LOOP;
    CLOSE emp_cur;
END;

EXEC list_emp;

EMPNO    ENAME
-----    -------
7369     SMITH
7499     ALLEN
7521     WARD
7566     JONES
7654     MARTIN
7698     BLAKE
7782     CLARK
7788     SCOTT
7839     KING
7844     TURNER
7876     ADAMS
7900     JAMES
7902     FORD
7934     MILLER

次のストアドプロシージャでは、IN OUT および OUT 引数を使用して、従業員の番号、名前、および仕事が返されます。 まず、検索は指定された従業員番号に基づいています。 結果が見つからない場合は、指定された名前が使用されます。 無記名ブロックでストアドプロシージャが呼び出されます。

CREATE OR REPLACE PROCEDURE emp_job (
    p_empno         IN OUT emp.empno%TYPE,
    p_ename         IN OUT emp.ename%TYPE,
    p_job           OUT    emp.job%TYPE
)
IS
    v_empno         emp.empno%TYPE;
    v_ename         emp.ename%TYPE;
    v_job           emp.job%TYPE;
BEGIN
    SELECT ename, job INTO v_ename, v_job FROM emp WHERE empno = p_empno;
    p_ename := v_ename;
    p_job   := v_job;
    DBMS_OUTPUT.PUT_LINE('Found employee # ' || p_empno);
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        BEGIN
            SELECT empno, job INTO v_empno, v_job FROM emp
                WHERE ename = p_ename;
            p_empno := v_empno;
            p_job   := v_job;
            DBMS_OUTPUT.PUT_LINE('Found employee ' || p_ename);
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                DBMS_OUTPUT.PUT_LINE('Could not find an employee with ' ||
                    'number, ' || p_empno || ' nor name, '  || p_ename);
                p_empno := NULL;
                p_ename := NULL;
                p_job   := NULL;
        END;
END;

DECLARE
    v_empno      emp.empno%TYPE;
    v_ename      emp.ename%TYPE;
    v_job        emp.job%TYPE;
BEGIN
    v_empno := 0;
    v_ename := 'CLARK';
    emp_job(v_empno, v_ename, v_job);
    DBMS_OUTPUT.PUT_LINE('Employee No: ' || v_empno);
    DBMS_OUTPUT.PUT_LINE('Name       : ' || v_ename);
    DBMS_OUTPUT.PUT_LINE('Job        : ' || v_job);
END;

Found employee CLARK
Employee No: 7782
Name       : CLARK
Job        : MANAGER

次の例は、プロシージャの宣言で AUTHID DEFINER および SET 句を使用する方法を示しています。 update_salary ストアドプロシージャでは、ストアドプロシージャを定義したロールの特権を、ストアドプロシージャを呼び出しているロールに付与します。

CREATE OR REPLACE PROCEDURE update_salary(id INT, new_salary NUMBER)
  SET SEARCH_PATH = 'public' SET WORK_MEM = '1MB'
  AUTHID DEFINER IS
BEGIN
  UPDATE emp SET salary = new_salary WHERE emp_id = id;
END;

SET 句を使用して、ストアドプロシージャの検索パスをパブリックに設定し、作業メモリを 1 MB に設定できます。 他のストアドプロシージャ、関数、およびオブジェクトは、これらの設定の影響を受けません。

この例では、AUTHID DEFINER 句で、ストアドプロシージャ内の文の実行を許可されていない可能性があるロールに特権を一時的に付与します。 ストアドプロシージャを呼び出すロールに関連付けられている特権を使用するようにサーバーに指示するには、AUTHID DEFINER 句を AUTHID CURRENT_USER 句に置き換えます。