CREATE PACKAGE

CREATE PACKAGE文は、データベースに一緒に格納される、関連するプロシージャやファンクション、その他のプログラム・オブジェクトをカプセル化したコレクションである、スタンドアロン・パッケージの仕様部を作成します。パッケージ仕様でこれらのオブジェクトを宣言します。パッケージ本体でこれらのオブジェクトを定義します。

必要な権限

CREATE PROCEDURE(所有者の場合)またはCREATE ANY PROCEDURE(非所有者の場合)。

TimesTen Scaleoutでの使用

この文は、TimesTen Scaleoutでサポートされています。

SQL構文

CREATE [OR REPLACE] PACKAGE [Owner.]PackageName
      [InvokerRightsClause] [AccessibleByClause]
      {IS|AS}
      PlsqlPackageSpec

InvokerRightsClause::=
AUTHID {CURRENT_USER | DEFINER}

AccessibleByClause::=
ACCESSIBLE BY (accessor[,...])

accessor::= 
[UnitKind][Owner.]UnitName

InvokerRightsClauseまたはAccessibleByClauseは任意の順序で指定できます。

パラメータ

パラメータ 説明

OR REPLACE

パッケージ仕様がすでに存在する場合に再作成するには、OR REPLACEを指定します。この句を使用して、パッケージを削除および再作成せずに既存のパッケージの仕様を変更します。パッケージ仕様を変更すると、そのパッケージ仕様はTimesTenで再コンパイルされます。

PackageName

パッケージの名前。

InvokerRightsClause

PL/SQLファンクションまたはプロシージャ内のSQL文が定義者権限で実行されるか実行者権限で実行されるかを指定できます。AUTHIDの設定は、実行時にPL/SQLプロシージャまたはファンクションによって発行されるSQL文の名前解決および権限チェックに次のように影響を与えます。

  • DEFINERを指定すると、SQLの名前解決および権限チェックは、プロシージャまたはファンクションの所有者(定義者、つまりプロシージャまたはファンクションがあるスキーマの所有者)が実行しているものとして実行されます。DEFINERがデフォルトです。

  • CURRENT_USERを指定すると、SQLの名前解決および権限チェックは、現在のユーザー(実行者)が実行しているものとして実行されます。

詳細は、『Oracle TimesTen In-Memory Databaseセキュリティ・ガイド』「定義者権限および実行者権限(AUTHID句)」を参照してください。

AccessibleByClause

この句は、パッケージを直接呼び出せる1つ以上のアクセッサ(PL/SQL単位)を指定する場合に使用します。パッケージにアクセスできるアクセッサのリストは、ホワイトリストと呼ばれます。ホワイト・リストを使用すると、PL/SQLオブジェクトにセキュリティ・レイヤーを追加できます。特に、ホワイト・リストにあるオブジェクトのみにパッケージへのアクセスを制限できます。

AccessibleByClauseは、CREATE PACKAGE文で1回のみ指定できます。

構文: ACCESSIBLE BY (accessor [,...])

accessor

AccessibleByClauseで使用されます。アクセッサは、パッケージを呼び出せるPL/SQLユニットです。

アクセッサは、AccessibleByClause句で複数回指定できます。

構文: [UnitKind][Owner.]UnitName

UnitKind

accessor句(AccessibleByClause句の一部)で使用されます。パッケージを呼び出せるPL/SQLユニットの種類を指定します。

  • UnitKindはオプションですが、指定する場合の有効なオプションは次のとおりです。
  • FUNCTION

  • PROCEDURE

  • PACKAGE

[Owner.]UnitName

accessor句(AccessibleByClause句の一部)で使用されます。パッケージを呼び出せるPL/SQLユニットの名前を指定します。UnitKindを指定する場合、UnitNameをこの種類のユニットの名前にする必要があります。たとえば、UnitKindPROCEDUREを指定する場合、UnitNameはプロシージャ名である必要があります。UnitNameは必須です。

Ownerは必要に応じて指定できます。Ownerを指定する場合、UnitNameがその所有者のスキーマ内に常駐する必要があります。Ownerを指定しない場合、UnitNameはパッケージを含むスキーマ内にある必要があります。

IS|AS

ISまたはASを指定して、ファンクションの本体を宣言します。

PlsqlPackageSpec

パッケージ仕様を指定します。型定義、カーソル宣言、変数宣言、定数宣言、例外宣言およびPL/SQLサブプログラム宣言を含めることができます。

説明

  • AccessibleByClause:

    • AccessibleByClauseは、トップレベルのパッケージ定義で有効です。パッケージ内の個々のプロシージャまたはファンクションにAccessibleByClauseを指定することはできません。また、CREATE PACKAGE BODY文でAccessibleByClauseは指定できません。

    • この句は、ヘルパー・パッケージへのアクセスを制限するために使用できます。たとえば、PL/SQLパッケージに特定の機能のAPIが定義されており、その機能が一連のヘルパー・プロシージャおよびファンクションを使用して実装されているとします。パッケージに定義されているAPIプロシージャやファンクションをコールできるようにのみアプリケーションを制限し、ヘルパー・プロシージャやファンクションを直接コールできないようにする必要があります。そのために、ACCESSIBLE BY句を使用できます。

    • コンパイラはACCESSIBLE BY句の構文の妥当性をチェックしますが、アクセッサが存在することはチェックしません。このため、所有者のスキーマにまだ存在しているアクセッサを定義できます。

    • パッケージを呼び出すと、コンパイラはまず呼出しの通常のアクセス権チェックを実行します。いずれかのチェックに失敗すると、呼出し元がアクセッサであっても呼出しは失敗します。呼出し時の通常のアクセス権チェックがすべて成功し、このパッケージにACCESSIBLE BY句がない場合、呼出しは成功します。パッケージにACCESSIBLE BY句がある場合、呼出し元がアクセッサである場合にのみ呼出しは成功します。

  • パッケージを作成または置き換えた場合、パッケージに付与された権限は同じままです。オブジェクトを削除して再作成した場合、元のオブジェクトに付与されていたオブジェクト権限は削除されます。

  • レプリケートされた環境で、CREATE PACKAGE文はレプリケートされません。詳細は、『Oracle TimesTen In-Memory Databaseレプリケーション・ガイド』「既存のアクティブ・スタンバイ・ペアでの新しいPL/SQLオブジェクトの作成」および「既存のクラシック・レプリケーション・スキームへのPL/SQLオブジェクトの追加」を参照してください。

Accessible By句の適切な使用方法の説明

この例は、AccessibleByClauseの正しい使用方法を示しています。この句は、CREATE PACKAGE文のトップレベルで指定されます。CallingProcプロシージャが存在する必要はないことに注意してください。

Command> CREATE OR REPLACE PACKAGE ProtectedPkg
           ACCESSIBLE BY (PROCEDURE CallingProc)
         AS
           PROCEDURE ProtectedProc;
         END;
         /
 
Package created.

Accessible By句の不適切な使用方法の説明

これらの例は、AccessibleByClauseの不適切な使用を示しています。最初の例では、パッケージ・プロシージャのAccessibleByClauseを使用しようとしてコンパイル・エラーが発生します。2番目の例では、CREATE PACKAGE BODY文でAccessibleByClauseを使用しようとしてコンパイル・エラーになります。

この例では、パッケージ・プロシージャでACCESSIBLE BY句を使用します。

Command> CREATE OR REPLACE PACKAGE ProtectedPkg1
         AS
           PROCEDURE ProtectedProc1 
           ACCESSIBLE BY (PROCEDURE CallingProc)
         END;
         /
         
Warning: Package created with compilation errors.
 
Command> SHOW ERRORS
Errors for PACKAGE PROTECTEDPKG1:
 
LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0      PLS-00157: Only schema-level programs allow ACCESSIBLE BY

この例では、CREATE PACKAGE BODY文でACCESSIBLE BY句を使用します。

Command> CREATE OR REPLACE PACKAGE ProtectedPkg3
           ACCESSIBLE BY (PROCEDURE CallingProc3)
         AS
           PROCEDURE ProtectedProc3;
         END;
         /
        
Package created.

Command> CREATE OR REPLACE PACKAGE BODY ProtectedPkg3
           ACCESSIBLE BY (PROCEDURE CallingProc3)
         AS
           PROCEDURE ProtectedProc3 AS
           BEGIN
             NULL;
           END;
           ;
         /
 
Warning: Package body created with compilation errors.
 
Command> SHOW ERRORS
Errors for PACKAGE BODY PROTECTEDPKG3:
 
LINE/COL ERROR
-------- -----------------------------------------------------------------
2/1      PLS-00103: Encountered the symbol "ACCESSIBLE" when expecting one of the
following:
 
  is as compress compiled wrapped

APIのみをヘルパー・パッケージにアクセス可能にする方法

この例では、AccessibleByClauseの使用を説明する一連のステップを示します。例では、SampleAPIパッケージおよびSampleHelperパッケージを作成します。ACCESSIBLE BY句は、SampleAPIパッケージのみがSampleHelperパッケージにアクセスできるように、SampleHelperで指定されています。

ステップ:

  1. SampleHelperパッケージを作成します。ACCESSIBLE BY句を指定し、SampleAPIパッケージにSampleHelperパッケージへのアクセス権を付与します。SampleAPIパッケージは、ホワイト・リストにあります。

    Command> CREATE OR REPLACE PACKAGE SampleHelper
               ACCESSIBLE BY (SampleAPI)
             AS
               PROCEDURE SampleH1;
               PROCEDURE SampleH2;
             END;
             /
     
    Package created.
    
  2. SampleHelperパッケージ本体を作成します。

    Command> CREATE OR REPLACE PACKAGE BODY SampleHelper
             AS
               PROCEDURE SampleH1 AS
               BEGIN
                 DBMS_OUTPUT.PUT_LINE('Sample helper procedure SampleH1');
               END;
               PROCEDURE SampleH2 AS
               BEGIN
                 DBMS_OUTPUT.PUT_LINE('Sample helper procedure SampleH2');
               END;
             END;
             /
     
    Package body created.
    
  3. SampleAPIパッケージを作成します。

    Command> CREATE OR REPLACE PACKAGE SampleAPI
             AS
               PROCEDURE p1;
               PROCEDURE p2;
             END;
             /
     
    Package created.
    
  4. SampleAPIパッケージ本体を作成します。p1プロシージャは、SampleHelper.SampleH1プロシージャを参照します。p2プロシージャは、SampleHelper.SampleH2プロシージャを参照します。

    Command> CREATE OR REPLACE PACKAGE BODY SampleAPI
             AS
               PROCEDURE p1 AS
               BEGIN
                 DBMS_OUTPUT.PUT_LINE('SampleAPI procedure p1');
                 SampleHelper.SampleH1;
               END;
               PROCEDURE p2 AS
               BEGIN
                 DBMS_OUTPUT.PUT_LINE('SampleAPI procedure p2');
                 SampleHelper.SampleH2;
               END;
             END;
             /
     
    Package body created.
    
  5. SampleAPI.p1プロシージャおよびSampleAPI.p2プロシージャをコールします。SampleAPIパッケージはSampleHelperパッケージのホワイト・リストにあり、実行は成功します。

    Command> SET SERVEROUTPUT ON
    Command> BEGIN
               SampleAPI.p1;
               SampleAPI.p2;
             END;
             /
    SampleAPI procedure p1
    Sample helper procedure SampleH1
    SampleAPI procedure p2
    Sample helper procedure SampleH2
     
    PL/SQL procedure successfully completed.
    
  6. SampleHelper.SampleH1プロシージャを直接コールします。アクセス権限が不十分なため、エラーが返されます。

    Command> BEGIN
               SampleHelper.SampleH1;
             END;
            /
     8503: ORA-06550: line 2, column 3:
    PLS-00904: insufficient privilege to access object SAMPLEHELPER
     8503: ORA-06550: line 2, column 3:
    PL/SQL: Statement ignored
    The command failed.