ヘッダーをスキップ

Oracle Rdb SQLリファレンス・マニュアル リリース7.2 E06178-01 |
| 目次 | 索引

戻る | 次へ |

# CREATE MODULE文

> Oracle Rdbデータベースにオブジェクトとしてモジュールを定義します。モジュールは、ファンクションとプロシージャとともに格納されます。SQLで記述された、データとともにデータベースに存在するファンクションまたはプロシージャは、ストアド・ファンクションまたはストアド・プロシージャと呼ばれます。同様に、データベースに格納されるモジュールはストアド・モジュールと呼ばれます。ストアド・ルーチンは、ストアド・プロシージャまたはストアド・ファンクションのいずれかを参照します。

> ストアド・プロシージャは、埋込みSQL、SQLモジュール言語または対話型SQLの単一文プロシージャでCALL文を使用して起動するか、複合文の内部でCALL文を使用して起動します。

> ストアド・ファンクションは、値式にファンクション名を指定して起動します。

> SQLでは、データベース内のストアド・ルーチンに対して格納、表示、削除、権限の付与および取消しを実行するメカニズムとして、モジュールの概念が適用されます。つまり、格納、削除、権限の付与および取消しは、個々のストアド・ルーチンに対しては実行できません。ストアド・ルーチンを削除する必要がある場合は、DROP FUNCTION routine-name CASCADE構文またはDROP PROCEDURE routine-name CASCADE構文を使用します。

> 通常、SQLはストアド・ルーチンではなく、モジュールを対象とします。ただし、DROP FUNCTION、DROP PROCEDURE、RENAME、SHOW FUNCTION、SHOW PROCEDUREおよびCALLの場合は除きます。SHOW FUNCTION文によって、ファンクションに関する情報が表示されます。SHOW PROCEDURE文によって、ストアド・モジュール内の個々のプロシージャが表示されます。CALL文では、単一のストアド・プロシージャのみを起動できます。

## 環境

> CREATE MODULE文は、単一文プロシージャで次のような場合に使用できます。

> - 対話型SQL内

> - プリコンパイル対象のホスト言語プログラムに埋め込まれる場合

> - SQLモジュールのプロシージャの一部として

> - 動的SQLで動的に実行される文として

## 形式

## 引数

> ### AUTHORIZATION auth-id

> モジュールの定義者を識別する名前であり、モジュール権限の検証に使用されます。

> 権限の検証の詳細は、「使用方法」を参照し、認可識別子の使用の詳細は、第2.2.2項を参照してください。

> ### COMMENT IS 'string'

> モジュール、ルーチンおよびパラメータに関するコメントを追加します。SQLでは、SHOW MODULE文の実行時にコメントのテキストが表示されます。コメントは一重引用符（'）で囲み、コメント内の複数の行はスラッシュ（/）で区切ります。

> ### compound-statement

> ストアド・ルーチン内に複数のSQL文を組み込むことができるようにします。詳細は、「複合文」を参照してください。

> ### compound-use-statement

> ストアド・ルーチン内に1つのSQL文を組み込むことができるようにします。詳細は、「複合文」を参照してください。

> ストアド・ファンクションを定義している場合、この単一文はRETURNS句である必要があります。

> ### data-type

> 有効なSQLデータ型です。明示的なデータ型の指定は、ドメイン名指定の代替手段です。データ型の詳細は、第2.3節を参照してください。

> ### declare-local-temporary-table-statement

> モジュールに対してローカル一時表を宣言します。詳細は、「DECLARE LOCAL TEMPORARY TABLE文」を参照してください。

> ### declare-transaction-statement

> モジュールに対してトランザクションを宣言します。declare-transaction-statementは、各モジュールに1つのみ許可されます。省略すると、DECLARE TRANSACTION READ WRITEが暗黙的に使用されます。詳細は、「DECLARE TRANSACTION文」を参照してください。

> ### declare-variable-statement

> モジュールに対してグローバル変数を宣言します。詳細は、「DECLARE変数文」を参照してください。

> ### DEFAULT value-expr

> INモードで定義したファンクションまたはプロシージャに対するパラメータのデフォルト値を指定します。このパラメータを省略するか、CALL文の引数リストまたはファンクションの起動でDEFAULTキーワードが指定される場合は、この句に指定したvalue-exprが使用されます。値式を明示的に指定しない場合は、パラメータでNULLがデフォルトとして使用されます。

> ### DETERMINISTIC

> ### NOT DETERMINISTIC

> この句は、問合せの有効範囲内で外部ファンクションの評価を制御します。

> - NOT DETERMINISTIC
>   NOT DETERMINISTIC句を指定すると、該当するファンクションが（単一問合せの有効範囲で）表示されるたびに、そのファンクションが強制的に評価されます。ファンクションの起動ごとに異なる結果が返される場合は、DETERMINISTIC句を使用する必要があります。

> - DETERMINISTIC
>   DETERMINISTIC句を指定すると、（単一問合せの有効範囲で）該当するファンクション式の単一評価が行われ、その結果の値が対応するファンクション式のすべての該当箇所で使用されます。DETERMINISTIC句を使用すると、この句を使用するたびにファンクションを起動するかどうかが評価されます。
>   次に例を示します。

>       SELECT * FROM T1 WHERE F1() > 0 AND F1() < 20;

>   F1ファンクションをDETERMINISTICとして定義すると、オプティマイザによっては、ファンクションF1()は1回のみ評価されます。F1ファンクションをNOT DETERMINISTICとして定義すると、ファンクションF1()は2回評価されます。
>   デフォルトはDETERMINISTICです。

> プロシージャ定義では、DETERMINISTIC句またはNOT DETERMINISTIC句は使用できません。

> ### domain-name

> CREATE DOMAIN文で作成されるドメインの名前です。ドメインの詳細は、「CREATE DOMAIN文」を参照してください。

> ### DEFAULT value-expr

> INモードで定義したファンクションまたはプロシージャに対するパラメータのデフォルト値を指定します。このパラメータを省略するか、CALL文の引数リストまたはファンクションの起動でDEFAULTキーワードが指定される場合は、この句に指定したvalue-exprが使用されます。値式を明示的に指定しない場合は、パラメータでNULLがデフォルトとして使用されます。

> ### IN

> ### OUT

> ### INOUT parameter-name

> ルーチンで使用されるパラメータ・モードを指定します。

> INパラメータはストアド・ルーチンに読み込まれるパラメータを指定するものですが、このパラメータは設定されません。OUTパラメータはデータの送信先となるパラメータを指定するものです。OUTパラメータは設定されますが、読み込まれません。INOUTパラメータは入力データ（読込み対象）および受信データ（設定対象）を指定するものです。INOUTパラメータは変更対象となるパラメータです。

> INパラメータはファンクションで使用できる唯一のモードです。

> 各パラメータ名はルーチン内で一意である必要があります。

> ### LANGUAGE SQL

> LANGUAGEキーワードおよびSQL引数は、モジュール内のプロシージャがホスト言語のプログラムではなく、SQL文によって起動されることを示します。

> 非ストアド・プロシージャの場合、LANGUAGEキーワードはホスト言語の名前を指定します。これは、モジュールのプロシージャをコールするプログラムを記述しているホスト言語を識別するものです。

> この句はOracle Rdbリリース7.1以降ではオプションです。

> ### module-name

> モジュールに割り当てるユーザー指定の名前です。

> ユーザー指定の名前の詳細は、第2.2節を参照してください。

> ### parameter-decl

> ストアド・ルーチンまたは外部ルーチンで使用されるパラメータおよびパラメータ・モードを指定します。

> ### PROCEDURE procedure-name

> ### FUNCTION function-name

> モジュール内のストアド・ルーチンまたは外部ルーチンに割り当てるユーザー指定の名前です。ストアド・ルーチンに対して指定する名前は、データベース定義内で一意である必要があります。

> ### RETURNS result-data-type

> ファンクション起動後のデータ型またはドメインを指定します。この句はファンクションの定義時にのみ有効です。RETURNS句はファンクションの定義時にのみ使用できます。

> ### routine-clause

> モジュール内に作成されるストアド・ファンクションまたはストアド・プロシージャの定義です。

> ### STORED NAME IS stored-name

> マルチスキーマ・データベースに作成したモジュールのプロシージャまたはファンクションへのアクセスに使用される名前を指定します。

> ### USAGE IS

> ファンクションまたはプロシージャのコール方法を指定します。

> - USAGE IS GLOBALは、ファンクションまたはプロシージャが現在のモジュールの外部からコール可能であることを示します。これはデフォルトです。

> - USAGE IS LOCALは、ルーチンの参照がモジュール内に限定されていることを示します。この句はCREATE MODULEには使用できますが、CREATE FUNCTIONまたはCREATE PROCEDUREには使用できません。

> ### VARIANT

> ### NOT VARIANT

> これらの句は、DETERMINISTIC句およびNOT DETERMINISTIC句と同義です。DETERMINISTIC句は、ファンクションに対する入力が同じであれば、出力も同じになることを示します。これはNOT VARIANT句と同義です。NOT DETERMINISTIC句は、ファンクションの出力は、その入力に依存しないことを示します。これはVARIANT句と同義です。

> この句は廃止予定です。かわりにDETERMINISTICを使用してください。この句は、問合せの有効範囲内で外部ファンクションの評価を制御します。

> - NOT DETERMINISTIC
>   NOT DETERMINISTIC句を指定すると、該当するファンクションが（単一問合せの有効範囲で）表示されるたびに、そのファンクションが強制的に評価されます。ファンクションの起動ごとに異なる結果が返される場合は、DETERMINISTIC句を使用する必要があります。

> - DETERMINISTIC
>   DETERMINISTIC句を指定すると、（単一問合せの有効範囲で）該当するファンクション式の単一評価が行われ、その結果の値が対応するファンクション式のすべての該当箇所で使用されます。DETERMINISTIC句を使用すると、この句を使用するたびにファンクションを起動するかどうかが評価されます。
>   次に例を示します。

>       SELECT * FROM T1 WHERE F1() > 0 AND F1() < 20;

>   F1ファンクションをDETERMINISTICとして定義すると、オプティマイザによっては、ファンクションF1()は1回のみ評価されます。F1ファンクションをNOT DETERMINISTICとして定義すると、ファンクションF1()は2回評価されます。
>   デフォルトはDETERMINISTICです。

> プロシージャ定義では、DETERMINISTIC句またはNOT DETERMINISTIC句は使用できません。

## 使用方法

> - データベース内にモジュールを作成するには、そのデータベースに対するCREATE権限が必要です。

> - モジュール定義にAUTHORIZATION句が指定されている場合、認可の検証では、指定した認可識別子が有効なユーザー名であるかどうかがチェックされます。OpenVMSでは、有効なユーザー名はOpenVMS権利識別子およびユーザー名です。
>   そのため、この認可IDの権限は、モジュール内で参照されるすべてのオブジェクトについて検証されます。システムではモジュール定義者の認可IDに基づいてモジュールのプロシージャが実行されるため、このようなモジュールは定義者権限モジュールです。
>   定義者権限モジュールを使用する場合、そのモジュールで参照されるオブジェクトに対してモジュールの定義者のみに権限があればよいため、データベース内で付与する必要のある権限の数を大幅に削減できます。モジュール内のプロシージャを実行する他のすべてのユーザーには、EXECUTE権限が必要です。
>   実行者権限モジュールは、AUTHORIZATION句を含まないストアド・モジュールです。実行時には、モジュール内のプロシージャを起動するユーザーの識別子が、そのモジュールで参照される全オブジェクトの権限の検証に使用されます。

> - 実行者権限ルーチンのコール前に、CURRENT_USERがSESSION_USERと同一であると設定されます。それぞれのルーチンがコールされると、この値がコール元から継承されるか、定義者権限ルーチンの場合はモジュールのAUTHORIZATION句から導出されます。そのため、CURRENT_USERはコール連鎖における最後の定義者権限ルーチンの認可を返します。

> - ストアド・プロシージャはCALL文を使用して起動します。また、ストアド・プロシージャは複合文や別のストアド・プロシージャからも起動できます。
>   ストアド・プロシージャの起動の詳細は、「単一文のCALL文」および「複合文のCALL文」を参照してください。

> - パラメータ・モードを省略すると、外部ルーチンおよびストアド・ファンクションに対してデフォルトでINが指定されます。ストアド・プロシージャの場合、使用方法で決まります。このような暗黙的な設定を確認するには、SHOW PROCEDUREおよびSHOW FUNCTIONを使用します。

> - 次に、ストアド・プロシージャと非ストアド・プロシージャの相違を示します。

>   - ストアド・プロシージャではパラメータによってNULL値を渡すことができますが、非ストアド・プロシージャでは標識変数を使用する必要があります。

>   - ストアド・プロシージャにはSQLCODE、SQLSTATE、SQLCAなどのステータス・パラメータを宣言できませんが、非ストアド・プロシージャにはステータス・パラメータを宣言する必要があります。

>   - ストアド・プロシージャではすべてのSQLデータ型を使用できます。非ストアド・プロシージャでは、使用するホスト言語によっては一部のデータ型を使用できません。

>   - ストアド・モジュール名および非ストアド・モジュール名は互いに一意である必要があります。アクティブな非ストアド・モジュールと同じ名前を持つストアド・モジュールを起動しようとすると、次のエラーが表示されます。

>         %RDB-E-IMP_EXC, facility-specific limit exceeded
>         -RDMS-E-MODEXTS, there is another module named SALARY_ROUTINES in
>         this database

> - ストアド・ルーチン名は、他のストアド・ルーチンおよび外部ルーチンにおいても一意である必要があります。

> - 特定のSQL要素を変更または削除すると、SQLでその要素を使用するストアド・ルーチンが無効になることがあります。
>   通常、制限付きDROP文はストアド・ルーチンの検証には影響しません。RESTRICTキーワードを指定した文を使用すると、ストアド・ルーチンに依存するオブジェクトの削除を回避できます。削除カスケード操作は正常に実行されますが、ストアド・ルーチンが無効になります。
>   表6-4に、SQLでストアド・ルーチンが無効になる可能性のある文を示します。

>   表6-4 ストアド・ルーチンが無効化される、または無効化されないALTER文およびDROP文
>   オブジェクト・ タイプ | SQL 文 | この文が失敗するか | ストアド・ルーチンは 無効化されるか | 依存性 タイプ1
>   --- | --- | --- | --- | ---
>   列 | ALTER TABLE DROP COLUMN | ○ | × | SR
>   | ALTER TABLE ADD COLUMN | × | ○ | LS
>   | ALTER TABLE ADD COLUMN | × | × | SR
>   | ALTER TABLE ALTER COLUMN AFTER COLUMN | × | ○ | LS
>   | ALTER TABLE ALTER COLUMN BEFORE COLUMN | × | ○ | LS
>   制約 | ALTER TABLE DROP CONSTRAINT | ○ | × | SR
>   | ALTER TABLE ADD CONSTRAINT | × | × | SRまたはDE
>   | RENAME CONSTRAINT | × | ×6 | DE
>   ドメイン | ALTER DOMAIN data type（パラメータ・リスト内） | ○ | × | SR2
>   | ALTER DOMAIN data type（プロシージャ・ブロック内） | × | × | SR3
>   | DROP DOMAIN | ○ | × | SRまたはSM
>   | RENAME DOMAIN | × | ×4 | SR
>   ファンクション | ALTER FUNCTION | × | × | SR
>   | DROP FUNCTION RESTRICT | ○ | × | SR
>   | DROP FUNCTION CASCADE | × | ○ | SR
>   | RENAME FUNCTION | × | ×4 | SR
>   モジュール | ALTER MODULE DROP FUNCTION RESTRICT | ○ | × | SR
>   | ALTER MODULE DROP FUNCTION CASCADE | × | ○ | SR
>   | ALTER MODULE DROP PROCEDURE RESTRICT | ○ | × | SR
>   | ALTER MODULE DROP PROCEDURE CASCADE | × | ○ | SR
>   | DROP MODULE RESTRICT | ○ | × | SR
>   | DROP MODULE CASCADE | × | ○ | SR
>   | RENAME MODULE | × | ×4 | SR
>   プロシージャ | ALTER PROCEDURE | × | × | SR
>   | DROP PROCEDURE RESTRICT | ○ | × | SR
>   | DROP PROCEDURE CASCADE | × | ○ | SR
>   | RENAME PROCEDURE | × | ×4 | SR
>   順序 | ALTER SEQUENCE | × | × | SR
>   | DROP SEQUENCE RESTRICT | ○ | × | SR
>   | DROP SEQUENCE CASCADE | × | ○ | SR
>   | RENAME SEQUENCE | × | ×4 | SR
>   シノニム | ALTER SYNONYM | × | ×5 | SR
>   | DROP SYNONYM RESTRICT | ○ | × | SR
>   | DROP SYNONYM CASCADE | × | ○ | SR
>   表 | ALTER TABLE | × | × | SR
>   | DROP TABLE RESTRICT | ○ | × | SR、LS、DRまたはSM
>   | DROP TABLE CASCADE | × | ○ | SRまたはLS
>   | RENAME TABLE | × | ×4 | SR
>   ビュー | DROP VIEW RESTRICT | ○ | × | SR、LSまたはDR
>   | DROP VIEW CASCADE | × | ○ | SRまたはLS
>   | RENAME VIEW | × | ×4 | SR

1依存性タイプ: DE（デフォルトで評価）、DR（デフォルトで予約）、LS（言語セマンティクス）、SR（ストアド・ルーチン）、SM（ストアド・モジュール）。
2Oracle Rdbでは、このドメインのパラメータ・リストの依存性はRDB$INTERRELATIONSではなくRDB$PARAMETERSに保持されます。
3Oracle Rdbでは、ドメインがストアド・ルーチン・ブロックにある場合、ルーチンの依存性はRDB$INTERRELATIONSに格納されます。
4RENAMEでは、削除されたシノニムが無効化されたルーチンである場合にのみ、古い名前に対してこのシノニムが追加されます。
5変更されたシノニムは同じ列またはパラメータ・リストのあるオブジェクト（表、ビュー、ファンクションまたはプロシージャ）を参照します。それ以外の場合、実行時にエラーが発生します。
6古い制約名がDECLARE TRANSACTION ... EVALUATING句で参照され、その後、この宣言されたトランザクションがルーチンの起動時に使用されると、エラーが発生します。

- コメントのそれぞれの文字列リテラルの最大長は1024文字です。

- ストアド・ファンクション内に、COMMIT文、ROLLBACK文、START TRANSACTION文、SET TRANSACTION文は指定できません。

- ファンクションは、値式を使用できる任意の場所で起動できます。

- Oracle Rdbには、ストアド・ルーチンで可能なネストの深さに関する制限は設定されていません。ここでは、メモリーとスタック・サイズによる制約のみを考慮する必要があります。

- ストアド・ルーチンでは、モジュール内に事前に定義した他のストアド・ルーチンを参照できます。「DECLARE STATEMENT文」および「DECLAREルーチン文」も参照してください。

- TRACE文は任意のストアド・ルーチンから使用できます。ただし、SQL内からTRACEフラグを有効にする場合は、ストアド・ルーチンを起動する前に有効にする必要があります。

- 通常、SQLは組み込まれているルーチンではなく、モジュールに対して機能します。ただし、DROP FUNCTION、DROP PROCEDURE、SHOW FUNCTION、SHOW PROCEDUREおよびCALLの場合は除きます。SHOW FUNCTION文によって、ファンクションに関する情報が表示されます。SHOW PROCEDURE文によって、個々のプロシージャが表示されます。

- mechanism-clauseは、SQLストアド・ファンクションまたはプロシージャでは使用できません。

- グローバル変数については、次の使用方法に注意します。

  - グローバル変数は、作成したモジュール内の任意のルーチンから（ローカル変数と同様に）参照できます。

  - ローカル変数とグローバル変数の名前が同じ場合、そのローカル変数が宣言されているファンクションまたはプロシージャの有効範囲では、ローカル変数がグローバル変数より優先されます。次に例を示します。

        SQL> SET FLAGS 'TRACE';
        SQL> CREATE MODULE SAMPLE
        cont>    DECLARE :IMAX INTEGER DEFAULT 100
        cont>    PROCEDURE TRACE_MAX;
        cont>    BEGIN
        cont>    DECLARE :IMAX INTEGER DEFAULT 0;
        cont>    TRACE :IMAX;
        cont>    END;
        cont> END MODULE;
        SQL> CALL TRACE_MAX();
        ~Xt: 0

  - All DEFAULT値句は、モジュールでファンクションまたはプロシージャを最初にコールしたときに評価されます。

  - データはDISCONNECT時にモジュールがアンロードされるまで維持されます。そのため、モジュール内のルーチンではグローバル変数を使用してデータを交換できます。

  - COMMIT文とROLLBACK文のどちらも、変数の状態には影響しません。つまり、変数に対する変更はロールバックされません。

- CURRENT_USERまたはCURRENT_UIDをストアド・ファンクションまたはストアド・プロシージャのデフォルトとして使用すると、これらはコール元から渡されたものとして評価され、作成されるルーチン内では評価されません。これは、該当するモジュールが定義者権限モジュールである（AUTHORIZATION句が指定されている）場合にのみ有効です。
  たとえば、次の例では、実行者は現行ユーザーとして返されますが、想定したようにはモジュールのAUTHORIZATIONは戻されません。

      SQL> create module DEF
      cont>     authorization FEENAN
      cont> procedure DEF1
      cont>     (in :a char(31)
      cont>      default current_user);
      cont> trace :a;
      cont> end module;
      SQL>
      SQL> set flags 'trace';
      SQL> begin
      cont> call DEF1 ();
      cont> end;
      ~Xt: SMITH

- デフォルトの式でSQLファンクションを使用して表にアクセスする場合、ファンクション内のLOCK TABLE文を使用して、該当する表をファンクション内またはネストされているコール先プロシージャ内で明示的にロックする必要があります。

- 外部ルーチンおよびストアド・ルーチンは、単一モジュール内に組み込むことができます。これには次のような利点があります。

  - DROP操作、GRANT操作およびREVOKE操作を簡略化し、複数のルーチンに対して単一文で実行できます。たとえば、DROP MODULEを使用すると、単一コマンドで外部ルーチンとストアド・ルーチンを削除できます。GRANTおよびREVOKEは、それぞれの外部ルーチンに対して個別に文を使用するのではなく、さらに大きなルーチンのセットに対して適用できます。

  - 関連するルーチンは外部ルーチン、ストアド・ルーチンのいずれであってもグループ化できるため、データベースのメンテナンスが簡略化されます。

  - 同じモジュール内の外部ルーチンは、同じデータベース環境を共有できます。これによって、たとえば、1つの外部ルーチンでカーソルをOPENし、別の外部ルーチンで行をFETCHし、さらに別の外部ルーチンでカーソルをCLOSEできます。
    一方、外部ルーチンをCREATE FUNCTION構文またはCREATE PROCEDURE構文で作成した場合は、そのルーチンのみがデータベース環境を使用します。

- ストアド・モジュールの名前は、SQLモジュール言語モジュールや、外部機能を実装するプリコンパイルされたSQLモジュールに使用されている名前とは別のものにする必要があります。ただし、同一の名前や類似する名前を保持しておくと、今後のアプリケーションのメンテナンスに役立つ場合もあります。

- 共有モジュール・データベース環境は、SQL文を実行する外部ルーチンでのみ有効です。

- 外部ルーチンがデータベースにアタッチしている場合、起動元のセッションが終了すると暗黙的に切断されます。
  ただし、現在のトランザクション、オープンなカーソル、および外部ファンクション用に開始したセッションは、DISCONNECTを使用する前に終了することをお薦めします。これは、起動元ルーチンと同じコンテキストでトランザクションの終了と切断を行う外部ルーチンを明示的にコールするか、またはNOTIFYルーチンを使用して暗黙的に終了します。

- CREATE MODULEの定義でdeclare-transaction-statementを省略すると、SQLによってデフォルトのDECLARE TRANSACTION READ WRITEが適用されます。

  ## 例

  > 例1: ストアド・モジュールおよびストアド・プロシージャの作成

  > 次の例では、対話型SQLを使用してストアド・モジュールおよびストアド・プロシージャを作成する方法を示します。