14.1 ACCESSIBLE BY句

ACCESSIBLE BY句は、他のユニットによるユニットまたはサブプログラムへのアクセスを制限します。

accessorリストは、アクセスできるユニットを明示的にリストします。accessorリストはパッケージ内の個々のサブプログラムで定義できます。パッケージ自体に定義されたaccessorリスト(ある場合)に加え、このリストがチェックされます。このリストは、サブプログラムへのアクセスを制限できるのみで、アクセスを広げることはできません。このコード管理機能は、内部プログラムの誤った使用を防止するために役立ちます。たとえば、1つのパッケージを再編成して、アクセス制限が必要な少数のプロシージャのパッケージと、パブリック・アクセスが必要な残りのユニットのパッケージという2つのパッケージにすることはできません。

ACCESSIBLE BY句は、オブジェクト型、オブジェクト型本体、パッケージ、およびサブプログラムの宣言で記述できます。

構文

accessible_by_clause ::=

セマンティクス

accessible_by_clause

accessor

[schema.]unit_name

エンティティを起動できるストアドPL/SQLユニットを指定します。

accessorは、ACCESSIBLE BY句が含まれるエンティティにアクセスできる別のPL/SQLエンティティを指定します。

ACCESSIBLE BY句が出現した場合、その句が出現したエンティティにアクセスできるのは、その句で指定されたエンティティのみです。

accessorは、ACCESSIBLE BY句で複数回記述できます。

ACCESSIBLE BY句は、ユニットの宣言で1回のみ記述できます。

accessorで指定されたエンティティが存在する必要はありません。

ACCESSIBLE BY句のあるエンティティが起動されると、すべてのチェックが実行された後、追加のアクセス・チェックが課されます。これらのチェックには、次のものがあります。

  • 起動されたユニットには、unit_nameunit_kindが起動元のユニットと同じaccessorが含まれている必要があります。

  • accessorスキーマが含まれている場合、起動元ユニットはそのスキーマに含まれている必要があります。

  • accessorスキーマが含まれていない場合は、起動元は起動されたエンティティと同じスキーマからのものである必要があります。

unit_kind

ユニットがFUNCTIONPACKAGEPROCEDURETRIGGERまたはTYPEのいずれであるかを指定します。

使用上のノート

unit_kindはオプションですが、ユニットの名前が同じ場合のあいまいさを避けるために指定することをお薦めします。たとえば、ファンクションと同じ名前でトリガーを定義することができます。

ACCESSIBLE BY句は、コールが直接行われた場合にのみアクセスを許可します。静的SQL、DBMS_SQLまたは動的SQLを介したアクセスの場合、チェックは失敗します。

パッケージ仕様部またはパッケージ本体の初期化プロシージャへのコールは、パッケージ仕様部のaccessorリストに対してチェックされます。

ユニットはそれ自体に常にアクセスできます。ユニット内の項目は、同じユニット内の他の項目を参照できます。

保護されたサブプログラムへのRPCコールは、コールの有効性のチェックに使用できるコンテキストがないため、コンパイル時と実行時のいずれの場合でも常に失敗します。

保護されたサブプログラムへの条件付きコンパイル・ディレクティブからのコールは失敗します。

例14-1 同じスキーマの最上位プロシージャへのアクセスの制限

この例は、最上位プロシージャtop_protected_procをコールできるのは現在のスキーマのプロシージャtop_trusted_procのみであることを示しています。ユーザーがtop_proctected_procを直接コールすることはできません。

Live SQL:

この例は、Oracle Live SQLの「同じスキーマの最上位プロシージャへのアクセスの制限」で表示および実行できます

PROCEDURE top_protected_proc
  ACCESSIBLE BY (PROCEDURE top_trusted_proc)
AS
BEGIN
  DBMS_OUTPUT.PUT_LINE('Processed top_protected_proc.');
END;

PROCEDURE top_trusted_proc AS
BEGIN
  DBMS_OUTPUT.PUT_LINE('top_trusted_proc calls top_protected_proc');
  top_protected_proc;
END;


EXEC top_trusted_proc;
top_trusted_proc calls top_protected_proc
Processed top_protected_proc.


EXEC top_protected_proc;
BEGIN top_protected_proc; END;

PLS-00904: insufficient privilege to access object TOP_PROTECTED_PROC

例14-2 任意のユニット名へのアクセスの制限

この例は、PL/SQLのunit_kindACCESSIBLE BY句で指定されていない場合、ユニット名が一致すれば、任意のunit kindからのコールが許可されることを示しています。ACCESSIBLE BY句で指定されているunit_kindが既存のオブジェクトに一致しない場合、コンパイル・エラーは発生しません。ファンクションと同じ名前でトリガーを定義することができます。unit_kindを指定することをお薦めします。

Live SQL:

この例は、Oracle Live SQLの「任意の種類のユニット名へのアクセスの制限」で表示および実行できます

PROCEDURE protected_proc2
  ACCESSIBLE BY (top_trusted_f)
AS
BEGIN
  DBMS_OUTPUT.PUT_LINE('Processed protected_proc2.');
END;

FUNCTION top_protected_f RETURN NUMBER
ACCESSIBLE BY (TRIGGER top_trusted_f ) AS
BEGIN
   RETURN 0.5;
END top_protected_f;

FUNCTION top_trusted_f RETURN NUMBER AUTHID DEFINER IS
  FUNCTION g RETURN NUMBER DETERMINISTIC IS
  BEGIN
     RETURN 0.5;
  END g;
BEGIN
  protected_proc2;
  RETURN g() - DBMS_RANDOM.VALUE();
END top_trusted_f;

SELECT top_trusted_f FROM DUAL;
   .381773176

1 row selected.

Processed protected_proc2.

例14-3 ストアド・プロシージャへのアクセスの制限

この例では、top_trusted_procプロシージャからのコールのみが可能なパッケージ・プロシージャを示します。サブプログラムの仕様部と本体のACCESSIBLE BY句が、一致している必要があります。accessorリストにこのプロシージャが含まれていないACCESSIBLE BY句のある既存のプロシージャに対してコールが行われた場合、エラーが発生します。

Live SQL:

この例は、Oracle Live SQLの「ストアド・プロシージャへのアクセスの制限」で表示および実行できます

CREATE OR REPLACE PACKAGE protected_pkg
AS
  PROCEDURE public_proc;
  PROCEDURE private_proc ACCESSIBLE BY (PROCEDURE top_trusted_proc);
END;

CREATE OR REPLACE PACKAGE BODY protected_pkg
AS
  PROCEDURE public_proc AS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('Processed protected_pkg.public_proc');
  END;
  PROCEDURE private_proc ACCESSIBLE BY (PROCEDURE top_trusted_proc) AS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('Processed protected_pkg.private_proc');
  END;
END;

CREATE OR REPLACE PROCEDURE top_trusted_proc 
AS
  BEGIN
     DBMS_OUTPUT.PUT_LINE('top_trusted_proc calls protected_pkg.private_proc ');
     protected_pkg.private_proc;
  END;
    
Procedure created.

EXEC top_trusted_proc;
top_trusted_proc calls protected_pkg.private_proc
Processed protected_pkg.private_proc

EXEC protected_pkg.private_proc
PLS-00904: insufficient privilege to access object PRIVATE_PROC