サブプログラムの各部
サブプログラムの先頭には、その名前およびオプションのパラメータ・リストを指定するサブプログラムのヘッダーがあります。
無名ブロックと同様に、サブプログラムには次の部分があります。
-
宣言部(オプション)
この部分では、ローカル型、カーソル、定数、変数、例外およびネストしたサブプログラムを宣言および定義します。これらの項目は、サブプログラムの実行が完了すると消滅します。
この部分は、プラグマを指定することもできます。
ノート:
無名ブロックの宣言部とは異なり、サブプログラムの宣言部は、キーワード
DECLARE
では始まりません。 -
実行部(必須)
この部分には、値の代入、実行の制御およびデータの操作を実行する1つ以上の文が含まれています。(アプリケーション設計プロセスの初期段階では、例5-31に示すとおり、この部分に
NULL
文のみを含めることも可能です。) -
例外処理部(オプション)
この部分には、ランタイム・エラーを処理するコードが含まれています。
ここでのトピック
関連項目:
-
プロシージャ宣言と定義の構文は、「プロシージャの宣言および定義」を参照してください
-
サブプログラムのパラメータの詳細は、「サブプログラムのパラメータ」を参照してください
例9-1 単純なPL/SQLプロシージャの宣言、定義および起動
この例では、無名ブロックでプロシージャの宣言と定義を同時に行い、そのプロシージャを3回起動しています。3回目の起動では、プロシージャの例外処理部で処理される例外が呼び出されています。
DECLARE first_name employees.first_name%TYPE; last_name employees.last_name%TYPE; email employees.email%TYPE; employer VARCHAR2(8) := 'AcmeCorp'; -- Declare and define procedure PROCEDURE create_email ( -- Subprogram heading begins name1 VARCHAR2, name2 VARCHAR2, company VARCHAR2 ) -- Subprogram heading ends IS -- Declarative part begins error_message VARCHAR2(30) := 'Email address is too long.'; BEGIN -- Executable part begins email := name1 || '.' || name2 || '@' || company; EXCEPTION -- Exception-handling part begins WHEN VALUE_ERROR THEN DBMS_OUTPUT.PUT_LINE(error_message); END create_email; BEGIN first_name := 'John'; last_name := 'Doe'; create_email(first_name, last_name, employer); -- invocation DBMS_OUTPUT.PUT_LINE ('With first name first, email is: ' || email); create_email(last_name, first_name, employer); -- invocation DBMS_OUTPUT.PUT_LINE ('With last name first, email is: ' || email); first_name := 'Elizabeth'; last_name := 'MacDonald'; create_email(first_name, last_name, employer); -- invocation END; /
結果:
With first name first, email is: John.Doe@AcmeCorp With last name first, email is: Doe.John@AcmeCorp Email address is too long.
ファンクションの追加部分
ファンクションの構造は、プロシージャと同じですが、次の点が異なります。
-
ファンクションのヘッダーには、ファンクションが戻す値のデータ型を指定する
RETURN
句が含まれている必要があります。(プロシージャのヘッダーには、RETURN
句を含めることはできません。) -
ファンクションの実行部では、すべての実行パスが
RETURN
文へ導かれる必要があります。そうではない場合、PL/SQLコンパイラによってコンパイル時に警告が発行されます。(プロシージャでは、RETURN
文はオプションであり、推奨されません。詳細は、「RETURN文」を参照してください。) -
ファンクションの宣言には、次に示すオプションを含めることができます。
オプション | 説明 |
---|---|
|
オプティマイザが冗長なファンクションの起動を回避するために役立ちます。 |
|
ファンクションのパラレル実行を可能にし、パラレルDML評価の同時セッションで安全に使用できるようにします。 |
|
行ソースとして使用するためにテーブル・ファンクションをパイプライン化します。 |
|
PL/SQLファンクション結果キャッシュに、ファンクションの結果を格納します。 |
関連項目:
-
前述の表内の項目の説明を含む、ファンクション宣言と定義の構文は、「ファンクションの宣言および定義」を参照してください
-
RESULT_CACHE
オプションの詳細は、「PL/SQLファンクション結果キャッシュ」を参照してください
例9-2 単純なPL/SQLファンクションの宣言、定義および起動
この例では、無名ブロックでファンクションの宣言と定義を同時に行い、そのファンクションを起動しています。
DECLARE -- Declare and define function FUNCTION square (original NUMBER) -- parameter list RETURN NUMBER -- RETURN clause AS -- Declarative part begins original_squared NUMBER; BEGIN -- Executable part begins original_squared := original * original; RETURN original_squared; -- RETURN statement END; BEGIN DBMS_OUTPUT.PUT_LINE(square(100)); -- invocation END; /
結果:
10000
RETURN文
RETURN
文は、サブプログラムまたはこの文を含む無名ブロックの実行を即座に終了させます。サブプログラムまたは無名ブロックでは、複数のRETURN
文を使用できます。
ここでのトピック
関連項目:
RETURN
文の構文は、「RETURN文」を参照してください
ファンクションのRETURN文
ファンクションでは、すべての実行パスがRETURN
文に続き、すべてのRETURN
文が式を指定している必要があります。RETURN
文は、ファンクション識別子に式の値を代入し、起動元に制御を戻します(ここで、起動直後に実行が再開します)。
ノート:
パイプライン・テーブル・ファンクションでは、RETURN
文で式を指定する必要はありません。パイプライン・テーブル・ファンクションの各部の詳細は、「パイプライン・テーブル・ファンクションの作成」を参照してください。
例9-3では、無名ブロックで同じファンクションを2回起動しています。1回目では、RETURN
文は起動元の文の内部に制御を戻します。2回目では、RETURN
文は起動元の文の直後の文に制御を戻します。
例9-4では、ファンクションに複数のRETURN
文が含まれますが、パラメータが0または1でない場合、実行パスがRETURN
文へ導かれません。このファンクションは、コンパイル時に「PLW-05005: サブプログラムFは、行11に値なしで戻ります」という警告が発生します。
例9-5は、例9-4と同様ですが、ELSE
句が追加されています。すべての実行パスがRETURN
文へ導かれるため、ファンクションのコンパイル時に警告PLW-05005は発生しません。
例9-3 ファンクション内にあるRETURN文の後での実行の再開
DECLARE x INTEGER; FUNCTION f (n INTEGER) RETURN INTEGER IS BEGIN RETURN (n*n); END; BEGIN DBMS_OUTPUT.PUT_LINE ( 'f returns ' || f(2) || '. Execution returns here (1).' ); x := f(2); DBMS_OUTPUT.PUT_LINE('Execution returns here (2).'); END; /
結果:
f returns 4. Execution returns here (1).Execution returns here (2).
例9-4 RETURN文へ導かれない実行パスを含むファンクション
CREATE OR REPLACE FUNCTION f (n INTEGER) RETURN INTEGER AUTHID DEFINER IS BEGIN IF n = 0 THEN RETURN 1; ELSIF n = 1 THEN RETURN n; END IF; END; /
例9-5 すべての実行パスがRETURN文へ導かれるファンクション
CREATE OR REPLACE FUNCTION f (n INTEGER)
RETURN INTEGER
AUTHID DEFINER
IS
BEGIN
IF n = 0 THEN
RETURN 1;
ELSIF n = 1 THEN
RETURN n;
ELSE
RETURN n*n;
END IF;
END;
/
BEGIN
FOR i IN 0 .. 3 LOOP
DBMS_OUTPUT.PUT_LINE('f(' || i || ') = ' || f(i));
END LOOP;
END;
/
結果:
f(0) = 1 f(1) = 1 f(2) = 4 f(3) = 9
プロシージャのRETURN文
プロシージャでは、RETURN
文は起動元に制御を戻します。ここで、起動すると実行が即座に再開します。RETURN
文では、式を指定できません。
例9-6では、RETURN
文は、起動元の文の直後の文に制御を戻しています。
例9-6 プロシージャ内にあるRETURN文の後での実行の再開
DECLARE PROCEDURE p IS BEGIN DBMS_OUTPUT.PUT_LINE('Inside p'); RETURN; DBMS_OUTPUT.PUT_LINE('Unreachable statement.'); END; BEGIN p; DBMS_OUTPUT.PUT_LINE('Control returns here.'); END; /
結果:
Inside p Control returns here.
無名ブロックのRETURN文
無名ブロックでは、RETURN
文によってそのブロックおよびすべての外側のブロックが終了されます。RETURN
文では、式を指定できません。
例9-7では、RETURN
文によって、内側と外側の両方のブロックが終了されています。
例9-7 無名ブロック内にあるRETURN文の後での実行の再開
BEGIN BEGIN DBMS_OUTPUT.PUT_LINE('Inside inner block.'); RETURN; DBMS_OUTPUT.PUT_LINE('Unreachable statement.'); END; DBMS_OUTPUT.PUT_LINE('Inside outer block. Unreachable statement.'); END; /
結果:
Inside inner block.