14 PL/Scopeの使用

PL/Scopeによって、強力で効率的なPL/Scopeソース・コード・ツールの開発が可能になります。このツールは、ソース・コードの参照および理解に費やされる時間を最小限にすることによって、PL/SQL開発者の生産性を向上させます。

PL/Scopeはアプリケーション開発者向けのものであり、通常は開発データベース環境で使用されます。

注意:

PL/Scopeでは、ソース・コードがラップされているPL/SQLユニットのデータを収集できません。PL/SQLソース・コードのラップの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

トピック:

PL/Scopeの概要

PL/Scopeはコンパイラ駆動方式のツールであり、PL/SQLとSQL識別子およびPL/SQLソース・コード内のSQL文の使用方法を収集します。

PL/Scopeはプログラム・ユニットのコンパイル時にPL/SQL識別子、SQL識別子およびSQL文のメタデータを収集し、静的データ・ディクショナリ・ビューで使用できるようにします。収集されたデータには識別子の型、使用方法(DECLARATION、DEFINITION、REFERENCE、CALL、ASSIGNMENT)およびソース・コードにおける各使用場所に関する情報が含まれています。

Oracle Database 12c リリース2 (12.2)以降では、PL/ScopeはPL/SQLユニット内の静的SQLと動的SQLの呼出し位置の発生をレポートするように拡張されています。ネイティブ動的SQL (EXECUTE IMMEDIATE、OPEN CURSOR FOR)とDBMS_SQLコールの呼出し位置が収集されます。動的SQL文は実行時に生成されるため、コンパイル時には呼出し位置のみを収集できます。新しいDBA_STATEMENTSビューで収集されたデータは他のデータ・ディクショナリ・ビューとともに問合せを行い、プロジェクトのプログラミングに必要な変更の対象範囲やコード分析の実行についての疑問に答えを出すために役立ちます。また、正しく実行されないSQL文のソースを特定するためにも有用です。PL/Scopeは、表、ビューおよびPL/SQLユニット間の依存関係についての洞察を提供します。このレベルの詳細は、必要な変更の程度を判断する移行評価ツールとして使用できます。

PL/Scopeは、次に示す疑問に答えを出す上で役立ちます。
  • 表yの列xはPL/SQLコードのどこで、どのように使用されるのか。

  • 自分のアプリケーションのPL/SQLコードのSQLに、TimesTenとの互換性があるかどうか。

  • 宣言されてはいるが使用されていない定数、変数および例外が、自分のアプリケーションの場合どれなのか。

  • 自分のコードにSQLインジェクションの危険性があるかどうか。

  • アプリケーションでコード化されたオプティマイザ・ヒントを使用するSQL文は何なのか。

  • BULK COLLECT句を持つSQLはどれなのか。SQLがどこから呼び出されるのか。

PL/Scopeの使用に必要な権限

PUBLICにはデフォルトで、様々なシステム表とビューに対するSELECT権限と、様々なPL/SQLオブジェクトに対するEXECUTE権限があります。

PL/Scopeデータは、DBA_IDENTIFIERSおよびDBA_STATEMENTSデータ・ディクショナリ・ビューで使用できます。ユーザーは、これらのビューでデータを問い合せる権限を持っている必要があります。

これらの関連ビューでは、次に示す権限が付与されています。

ビュー名 ロールに付与された権限
USER_IDENTIFIERS PUBLICへのREAD
ALL_IDENTIFIERS PUBLICへのREAD
DBA_IDENTIFIERS SELECT_CATALOG_ROLEへのSELECT
USER_STATEMENTS PUBLICへのREAD
ALL_STATEMENTS PUBLICへのREAD
DBA_STATEMENTS SELECT_CATALOG_ROLEへのSELECT

データベース管理者は次のような問合せを使用して、これらのビューに対する権限のリストを検証できます。

SELECT *  
FROM   SYS.DBA_TAB_PRIVS  
WHERE  GRANTEE = 'PUBLIC' 
AND TABLE_NAME IN ('ALL_IDENTIFIERS','USER_IDENTIFIERS','ALL_STATEMENTS','USER_STATEMENTS');

識別子と文の収集の指定

デフォルトでは、PL/ScopeはPL/SQLソース・プログラムの識別子と文のデータを収集しません。収集対象を有効化し制御するには、PL/SQLコンパイル・パラメータPLSCOPE_SETTINGSを設定します。

Oracle Database 12c リリース2 (12.2)以降では、PLSCOPE_SETTINGSに新しい構文があります。この構文は、識別子とSQL文のメタデータを収集するためのコントロールとオプションを、さらに提供します。メタデータは、静的データ・ディクショナリ・ビューDBA_IDENTIFIERSDBA_STATEMENTSに収集されます。

パッケージ本体にある識別子など、PL/SQLソース・プログラムのすべての識別子用のデータをPL/Scopeによって収集するには、PL/SQLコンパイル・パラメータPLSCOPE_SETTINGS'IDENTIFIERS:ALL'に設定します。 IDENTIFIERS句に使用できる値は、ALL, NONE (デフォルト)、PUBLIC, SQLおよびPLSQLです。新しいSQL識別子は、ALIAS、COLUMN、MATERIALIZED VIEW、OPERATOR、TABLEおよびVIEWです。拡張されたメタデータ収集により、アプリケーションを理解する上で役立つレポートを生成できます。PL/Scopeは、PL/SQLアプリケーションのコード化プロジェクトの複雑さを、これまでよりも細かく評価できるツールとして使用できるようになりました。

PL/SQLソース・プログラムで使用される、すべてのSQL文のPL/Scopeデータを収集するには、PL/SQLコンパイル・パラメータPLSCOPE_SETTINGS'STATEMENTS:ALL'に設定します。デフォルト値はNONEです。

注意:

すべての識別子と文を収集すると、大量のデータが生成され、コンパイル時間が長くなる可能性があります。

PL/Scopeでは、収集するデータをSYSAUX表領域に格納します。プログラム・ユニットのコンパイル中に、PL/Scope収集が有効でSYSAUX表領域が使用不可の場合、PL/Scopeはコンパイルされたオブジェクトのデータを収集しません。コンパイラから警告は発行されませんが、USER_ERRORS内に警告が保存されます。

関連項目:

PL/Scopeデータによる領域の使用量

PL/ScopeのデータはSYSAUX表領域に格納されます。SYSDBAとしてログオンしている場合は、例14-1の問合せを使用してPL/Scopeデータが使用している領域の容量を表示できます。

例14-1 PL/Scopeデータによる領域の使用量

問合せ:

SELECT SPACE_USAGE_KBYTES
FROM V$SYSAUX_OCCUPANTS
WHERE OCCUPANT_NAME='PL/SCOPE';
 

結果:

SPACE_USAGE_KBYTES
------------------
              1920
 
1 row selected.

関連項目:

SYSAUX表領域の管理の詳細は、『Oracle Database管理者ガイド』を参照してください。

PL/Scopeデータの表示

PL/Scopeで収集したデータを表示するには、次のいずれかを使用できます。

PL/SQLおよびSQL識別子の静的データ・ディクショナリ・ビュー

静的データ・ディクショナリ・ビューのファミリDBA_IDENTIFIERSでは、その型や使用方法などのPL/Scope識別子に関する情報が表示されます。

トピック:

PL/Scopeが収集するPL/SQLおよびSQL識別子の型

表14-1に、PL/Scopeが収集する識別子の型をアルファベット順に示します。表14-1の識別子の型は、DBA_IDENTIFIERS静的データ・ディクショナリ・ビューのファミリのTYPE列に表示されます。

注意:

PLSCOPE_SETTINGS='IDENTIFIERS:ALL'でコンパイルされていないコンパイル・ユニットに宣言された識別子は、DBA_IDENTIFIERS静的データ・ディクショナリ・ビューに表示されません。

ROWNUMなどの疑似列は、ユーザー定義の識別子ではないため、サポートされていません。

PL/Scopeはリテラル文字列の列名を無視します。

表14-1 PL/Scopeが収集する識別子の型

TYPE列の値 コメント

ALIAS

Oracle Database 12c リリース2 (12.2)で導入された、新しいSQL識別子です。

ASSOCIATIVE ARRAY

COLUMN

Oracle Database 12c リリース2 (12.2)で導入された、新しいSQL識別子です。

CONSTANT

CURSOR

BFILE DATATYPE

BLOB DATATYPE

BOOLEAN DATATYPE

CHARACTER DATATYPE

CLOB DATATYPE

DATE DATATYPE

INTERVAL DATATYPE

NUMBER DATATYPE

TIME DATATYPE

TIMESTAMP DATATYPE

DATATYPEは、STANDARDパッケージで宣言されたベース型です。

EXCEPTION

FORMAL IN

FORMAL IN OUT

FORMAL OUT

FUNCTION

INDEX TABLE

ITERATOR

イテレータはFORループの索引です。

LABEL

ラベル宣言もコンテキストとして機能します。

LIBRARY

MATERIALIZED VIEW

Oracle Database 12c リリース2 (12.2)で導入された、新しいSQL識別子です。

NESTED TABLE

OBJECT

OPAQUE

内部不透明型にはANYDATAおよびXMLTypeがあります。

OPERATOR

Oracle Database 12c リリース2 (12.2)で導入された、新しいSQL識別子です。

PACKAGE

PROCEDURE

RECORD

REFCURSOR

SEQUENCE

Oracle Database 12c リリース2 (12.2)で導入された、新しいSQL識別子です。

SUBTYPE

SYNONYM

PL/Scopeでは、シノニムのベース・オブジェクト名は解決しません。シノニムのベース・オブジェクト名を調べるには、*_SYNONYMSを問い合せます。

TABLE

Oracle Database 12c リリース2 (12.2)で導入された、新しいSQL識別子です。

TRIGGER

UROWID

VARIABLE

オブジェクト属性、ローカル変数、パッケージ変数、レコード・フィールドのいずれにもできます。

VARRAY

VIEW

この型は、ビューの編集に使用されます。

Oracle Database 12c リリース2 (12.2)で導入された、新しいSQL識別子です。

関連項目:

ストアド・オブジェクト内の識別子の詳細は、『Oracle Databaseリファレンス』を参照してください。

識別子の使用方法について

PL/Scopeは、識別子のかわりに実行されるアクションを説明する動詞として使用します。

表14-2に、PL/Scopeがレポートする使用方法をアルファベット順に示します。表14-2の識別子のアクションは、DBA_IDENTIFIERS静的データ・ディクショナリ・ビューのファミリのUSAGE列に表示されます。このビューについては、『Oracle Databaseリファレンス』で説明されています。

表14-2 PL/Scopeがレポートする使用方法

USAGE列の値 説明:

ASSIGNMENT

代入は、VARIABLEなどの値を保持できる識別子に対してのみ可能です。

代入には次のものがあります。

  • 代入演算子の左側での識別子の使用

  • FETCH文のINTO句での識別子の使用

  • サブプログラムへの識別子の参照渡し(OUTモード)

  • OUTまたはIN OUTモードでの、EXECUTE IMMEDIATE文のUSING句における識別子のバインド変数としての使用

IN OUTモードでサブプログラムに渡される識別子には、REFERENCE使用方法(INに対応)とASSIGNMENT使用方法(OUTに対応)の両方があります。

式およびネストした副問合せは、割当てソースとしてサポートされていません。

CALL

PL/Scopeのコンテキストでは、CALLはコール・スタックの上にコールをプッシュする操作です。つまり、次のようになります。

  • FUNCTIONまたはPROCEDUREへのコール

  • カーソル識別子の実行またはフェッチ(SQLへの論理コール)

GOTO文または例外の発生はどちらもコール・スタックの上にコールをプッシュしないため、CALLではありません。

DECLARATION

DECLARATIONは、識別子が存在し、それぞれの識別子に1つずつDECLARATIONがあることをコンパイラに通知します。各DECLARATIONは、関連データ型を持つことができます。

ループ索引宣言の場合、(*_IDENTIFIERSビューの)LINEおよびCOLは、暗黙的にループ索引を宣言するFOR句の行および列です。

ラベル索引宣言の場合、LINEおよびCOLは、デリミタ<<および>>内でラベルが出現する(および暗黙的に宣言される)行および列です。

DEFINITION

DEFINITIONは、以前に宣言した識別子を実装または使用する方法をコンパイラに通知します。

次の各識別子の型にそれぞれDEFINITIONがあります。

  • EXCEPTION(複数定義が可能)

  • FUNCTION

  • OBJECT

  • PACKAGE

  • PROCEDURE

  • TRIGGER

最上位の識別子の場合のみ、DEFINITIONおよびDECLARATIONは同じ場所にあります。

REFERENCE

REFERENCEは、その値を変更せずに識別子を使用します。

参照には次のものがあります。

  • 例外識別子の発生。

  • 変数または仮パラメータの宣言での型識別子の使用。

  • あるフィールドにアクセスするための複数のフィールドが型に含まれている変数識別子の使用。たとえば、myrecordvar.myfield := 1では、myrecordvarに対して参照が行われ、myfieldに対して代入が行われます。

  • FETCHを除く任意の目的でのカーソルの使用。

  • サブプログラムへの識別子の値渡し(INモード)。

  • INまたはIN OUTモードでの、EXECUTE IMMEDIATE文のUSING句における識別子のバインド変数としての使用

IN OUTモードでサブプログラムに渡される識別子には、REFERENCE使用方法(INに対応)とASSIGNMENT使用方法(OUTに対応)の両方があります。

識別子の使用方法: 一意キー

すべての識別子の使用方法には、コード・ユニット内で一意の数値IDが指定されます。  これは識別子のUSAGE_IDです。

*_IDENTIFIERSビューの各行は、PL/SQLユニットの識別子の一意の使用方法を表します。これらの各ビューでは、次のものがコンパイル・ユニット内で同等の一意キーです。

  • LINECOLUSAGE

  • USAGE_ID

注意:

IN OUTモードでサブプログラムに渡される識別子では、*_IDENTIFIERSREFERENCE使用方法(INに対応)およびASSIGNMENT使用方法(OUTに対応)の2つの行があります。

この例は、PROCEDURE p1に対して生成されたUSAGE_IDを示しています。

CREATE OR REPLACE PROCEDURE p1 (a OUT VARCHAR2) 
IS 
  b VARCHAR2(100) := 'hello FROM p1'; 
BEGIN 
  a := b; 
END;
/

SELECT USAGE_ID, USAGE, NAME
FROM ALL_IDENTIFIERS
WHERE OBJECT_NAME = 'P1'
ORDER BY USAGE_ID;
         1 DECLARATION P1
         2 DEFINITION  P1
         3 DECLARATION A
         4 REFERENCE   VARCHAR2
         5 DECLARATION B
         6 REFERENCE   VARCHAR2
         7 ASSIGNMENT  B
         8 ASSIGNMENT  A
         9 REFERENCE   B

関連項目:

*_IDENTIFIERSビューの使用方法は、「識別子の使用方法について」を参照してください。

識別子の使用方法について: コンテキスト

識別子の使用方法は、他の識別子の使用方法のコンテキストにすることができます。  これは、使用方法間の1対多の親子関係を作成します。親コンテキストの使用方法でのUSAGE_IDは、子の使用方法ではUSAGE_CONTEXT_IDになります。

コンテキストは、複数の使用方法の間の関係を検出する場合に役立ちます。最上位のスキーマ・オブジェクト宣言および定義を除き、識別子のすべての使用方法は別の使用方法のコンテキストで発生します。

デフォルトのトップレベルのコンテキスト(すべてのトップレベルのオブジェクトが含まれる)は、0のUSAGE_CONTEXT_IDによって識別されます。

例:

  • ローカル変数宣言は、最上位のプロシージャ宣言のコンテキスト内で発生します。

  • x VARCHAR2(10)など、識別子が変数として宣言される場合、VARCHAR2型参照のUSAGE_CONTEXT_IDには、x宣言のUSAGE_IDが挿入され、変数宣言をその型に関連付けることができます。

つまり、例14-2に示すように、USAGE_CONTEXT_IDUSAGE_IDに対する再帰外部キーです。

例14-2 USAGE_CONTEXT_IDおよびUSAGE_ID

ALTER SESSION SET PLSCOPE_SETTINGS = 'IDENTIFIERS:ALL';

CREATE OR REPLACE PROCEDURE a (p1 IN BOOLEAN) AUTHID DEFINER IS
  v PLS_INTEGER;
BEGIN
  v := 42;
  DBMS_OUTPUT.PUT_LINE(v);
  RAISE_APPLICATION_ERROR (-20000, 'Bad');
EXCEPTION
  WHEN Program_Error THEN NULL;
END a;
/
CREATE or REPLACE PROCEDURE b (
  p2 OUT PLS_INTEGER,
  p3 IN OUT VARCHAR2
)  AUTHID DEFINER
IS
  n NUMBER;
  q BOOLEAN := TRUE;
BEGIN
  FOR j IN 1..5 LOOP
    a(q); a(TRUE); a(TRUE);
    IF j > 2 THEN
       GOTO z;
    END IF;
  END LOOP;
<<z>> DECLARE
  d CONSTANT CHAR(1) := 'X';
  BEGIN
    SELECT COUNT(*) INTO n FROM Dual WHERE Dummy = d;
  END z;
END b;
/
WITH v AS (
  SELECT    Line,
            Col,
            INITCAP(NAME) Name,
            LOWER(TYPE)   Type,
            LOWER(USAGE)  Usage,
            USAGE_ID,
            USAGE_CONTEXT_ID
    FROM USER_IDENTIFIERS
      WHERE Object_Name = 'B'
        AND Object_Type = 'PROCEDURE'
)
SELECT RPAD(LPAD(' ', 2*(Level-1)) ||
                 Name, 20, '.')||' '||
                 RPAD(Type, 20)||
                 RPAD(Usage, 20)
                 IDENTIFIER_USAGE_CONTEXTS
  FROM v
  START WITH USAGE_CONTEXT_ID = 0
  CONNECT BY PRIOR USAGE_ID = USAGE_CONTEXT_ID
  ORDER SIBLINGS BY Line, Col
/

結果:

IDENTIFIER_USAGE_CONTEXTS
-------------------------------------------------------------
B................... procedure           declaration
  B................. procedure           definition
    P2.............. formal out          declaration
      Pls_Integer... subtype             reference
    P3.............. formal in out       declaration
      Varchar2...... character datatype  reference
    N............... variable            declaration
      Number........ number datatype     reference
    Q............... variable            declaration
      Q............. variable            assignment
      Boolean....... boolean datatype    reference
    J............... iterator            declaration
      A............. procedure           call
        Q........... variable            reference
      A............. procedure           call
      A............. procedure           call
      J............. iterator            reference
      Z............. label               reference
    Z............... label               declaration
      D............. constant            declaration
        D........... constant            assignment
        Char........ subtype             reference
識別子のシグネチャについて

識別子のシグネチャは、プログラム・ユニット内および複数のプログラム・ユニット間で一意のものです。つまり、シグネチャは複数の識別子が同じ名前であっても、同じプログラム・ユニット内に定義されているか、または異なるプログラム・ユニットに定義されているかを区別します。

例14-3のプログラム・ユニットの場合、p5という名前の2つの識別子があり、静的データ・ディクショナリ・ビューUSER_IDENTIFIERSNAMEp5という行が複数ありますが、これらの行のSIGNATUREは異なるものです。外部プロシージャp5に関連付けられた行に1つのシグネチャがあり、内部プロシージャp5に関連付けられた行には別のシグネチャがあります。プログラム・ユニットqがプロシージャp5をコールする場合、qUSER_IDENTIFIERSビューには、NAMEp5SIGNATUREが外部プロシージャp5のシグネチャの行があります。

例14-3 p5という名前の2つの識別子を持つプログラム・ユニット

この例はp5という名前の2つの識別子を持つプログラム・ユニットを示して、シグネチャの一意性を明示しています。

CREATE OR REPLACE PROCEDURE p5 AUTHID DEFINER IS
  PROCEDURE p5 IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('Inner p5');
  END p5;
BEGIN
  DBMS_OUTPUT.PUT_LINE('Outer p5');
  p5();
END p5;
/

SELECT LINE || ' > ' || TEXT
FROM   ALL_SOURCE
WHERE  NAME = 'P5'
   AND TYPE = 'PROCEDURE'
ORDER BY LINE;
1 > PROCEDURE p5 AUTHID DEFINER IS
2 >   PROCEDURE p5 IS
3 >   BEGIN
4 >     DBMS_OUTPUT.PUT_LINE('Inner p5');
5 >   END p5;
6 > BEGIN
7 >   DBMS_OUTPUT.PUT_LINE('Outer p5');
8 >   p5();
9 > END p5;

次の問合せは、PL/SQLユニットのSIGNATUREが、内部と外部のp5のDECLARATIONとDEFINITIONで同じであることを示しています。

SELECT SIGNATURE, USAGE, LINE, COL, USAGE_ID, USAGE_CONTEXT_ID 
FROM   ALL_IDENTIFIERS
WHERE OBJECT_NAME = 'P5'
ORDER BY LINE, COL, USAGE_ID;
75CD5986BA2EE5C61ACEED8C7162528F DECLARATION          1         11          1       0
75CD5986BA2EE5C61ACEED8C7162528F DEFINITION           1         11          2       1
33FB9F948F526C4B0634C0F35DFA91F6 DECLARATION          2         13          3       2
33FB9F948F526C4B0634C0F35DFA91F6 DEFINITION           2         13          4       3
33FB9F948F526C4B0634C0F35DFA91F6 CALL                 8          3          7       2
CREATE OR REPLACE PROCEDURE q AUTHID DEFINER IS
BEGIN
  p5();
END q;
/
EXEC q;
Outer p5
Inner p5
SELECT SIGNATURE, USAGE, LINE, COL, USAGE_ID, USAGE_CONTEXT_ID
FROM   ALL_IDENTIFIERS
WHERE OBJECT_NAME = 'Q'
AND NAME = 'P5'
ORDER BY LINE, COL, USAGE_ID;
75CD5986BA2EE5C61ACEED8C7162528F CALL                 3          3          3       2

例14-4 VARCHAR2のすべての使用方法の検索

識別子のシグネチャは、グローバルに一意です。これは、データベースのすべてのユニット内で識別子のすべての使用方法を検索するために役立ちます。  この例は、VARCHAR2のすべての使用方法を検索する問合せを示しています。

SELECT UNIQUE OBJECT_NAME uses_varchar2 
FROM   ALL_IDENTIFIERS 
WHERE  SIGNATURE = (SELECT SIGNATURE 
                    FROM   ALL_IDENTIFIERS 
                    WHERE  OBJECT_NAME = 'STANDARD' 
                           AND OWNER = 'SYS' 
                           AND USAGE = 'DECLARATION' 
                           AND NAME = 'VARCHAR2') 
ORDER  BY OBJECT_NAME;

SQL文の静的データ・ディクショナリ・ビュー

DBA_STATEMENTS静的ディクショナリ・ビュー・ファミリは、PL/Scopeによって収集されたSQL文を説明します。

Oracle Database 12c リリース2 (12.2.0.1)以降では、新しいビューDBA_STATEMENTSが、PL/SQLユニット内の静的SQLの発生をレポートします。これは、SQL_ID、正規文のテキスト、文タイプ、有用な文使用の属性、シグネチャおよびPL/SQLコード内の場所についての情報を提供します。各行は、PL/SQLコード内のSQL文のインスタンスを表します。

PL/Scopeが収集するSQL文の型

PL/Scope文タイプは、PL/SQLで使用されるSQL文を表します。

PL/SQLでの実行や、それ以外のSQL操作に使用できる文に対応するSQL文の型。文タイプは、DBA_STATEMENTS静的データ・ディクショナリ・ビュー・ファミリのTYPE列に表示されます。

このメタデータを収集するには、PL/SQLユニットをPLSCOPE_SETTINGS='STATEMENTS:ALL'でコンパイルする必要があります。

PL/Scopeが収集するSQL文の型を次に示します。
  • SELECT

  • UPDATE

  • INSERT

  • DELETE

  • MERGE

  • EXECUTE IMMEDIATE

  • SET TRANSACTION

  • LOCK TABLE

  • COMMIT

  • SAVEPOINT

  • ROLLBACK

  • OPEN

  • CLOSE

  • FETCH

文の場所: 一意キー

DBA_STATEMENTSビューの各行は、PL/SQLユニット内のSQL文の、一意の場所を表します。これは、コンパイル・ユニット内の一意のキーに相当します。

次に示す列は、PL/SQLコード内の文の位置を判別するために使用されます。

  • OWNER、OBJECT_NAME、OBJECT_TYPE、LINE、COL

  • USAGE_ID

USAGE_IDは、PL/SQLユニット内で一意に定義されます。識別子とは異なり、SQL文には別の使用方法(DECLARATIONASSIGNMENTまたはREFERENCEなど)がありません。すべての文は、SQLエンジンに対する暗黙のCALLとみなされます。そのため、DBA_STATEMENTSビューにUSAGE列はありませんが、USAGE_IDを使用します。

例14-5 USAGE_ID列を使用したSQL識別子と文の問合せ

PROCEDURE p1 (p_cust_id   NUMBER, 
              p_cust_name OUT VARCHAR2) 
IS 
BEGIN 
    SELECT (SELECT CUST_FIRST_NAME 
            FROM   CUSTOMERS) 
    INTO   p_cust_name 
    FROM   CUSTOMERS 
    WHERE  CUSTOMER_ID = p_cust_id; 
END; 

SELECT USAGE_ID, TYPE, NAME, USAGE, LINE, COL 
FROM ( SELECT USAGE_ID, TYPE, NAME, USAGE, LINE, COL
       FROM ALL_IDENTIFIERS
       WHERE OBJECT_NAME = 'P1'
       UNION
       SELECT USAGE_ID, TYPE, 'SQL STATEMENT', " ", LINE, COL
       FROM ALL_STATEMENTS
       WHERE OBJECT_NAME = 'P1')
ORDER BY USAGE_ID;
USAGE_ID TYPE               NAME            USAGE        LINE   COL
---------- ------------------ --------------- ----------- ----- -----
         1 PROCEDURE          P1              DECLARATION     1    11
         2 PROCEDURE          P1              DEFINITION      1    11
         3 FORMAL IN          P_CUST_ID       DECLARATION     1    15
         4 NUMBER DATATYPE    NUMBER          REFERENCE       1    25
         5 FORMAL OUT         P_CUST_NAME     DECLARATION     1    33
         6 CHARACTER DATATYPE VARCHAR2        REFERENCE       1    49
         7 SQL STATEMENT      SELECT                          3     3
         8 TABLE              CUSTOMERS       REFERENCE       4    10
         9 FORMAL IN          P_CUST_ID       REFERENCE       4    38
        10 COLUMN             CUSTOMER_ID     REFERENCE       4    26
        11 FORMAL OUT         P_CUST_NAME     ASSIGNMENT      3    31
        12 COLUMN             CUST_FIRST_NAME REFERENCE       3    10
SQL文に使用方法について: コンテキスト

文は、他の文や識別子のコンテキストとして機能することができます。文は、他の文や識別子のコンテキスト内に置くこともできます。

USAGE_CONTEXT_ID列は、文のコンテキストを判別するために使用されます。文の中に現れるすべての識別子は、その文のコンテキストの中に存在することになります。

式およびネストした副問合せは、割当てソースとしてサポートされていません。

例14-6 DBA_STATEMENTS USAGE_CONTEXT_IDを使用した識別子の問合せ

この例では、USAGE_CONTEXT_ID列を使用して SELECT文のコンテキスト内にある識別子を取得する方法を示しています。

PROCEDURE p1 (p_cust_id   NUMBER, 
              p_cust_name OUT VARCHAR2) 
IS 
BEGIN 
    SELECT (SELECT CUST_FIRST_NAME 
            FROM   CUSTOMERS) 
    INTO   p_cust_name 
    FROM   CUSTOMERS 
    WHERE  CUSTOMER_ID = p_cust_id; 
END; 

SELECT USAGE_ID, LPAD(' ', 2*(level-1)) || TO_CHAR(USAGE) || ' ' || NAME usages, LINE, COL
FROM ( SELECT OBJECT_NAME, USAGE, USAGE_ID, USAGE_CONTEXT_ID, NAME, LINE, COL
       FROM ALL_IDENTIFIERS
       WHERE OBJECT_NAME = 'P1'
       UNION
       SELECT OBJECT_NAME, TYPE usage, USAGE_ID, USAGE_CONTEXT_ID, 'Statement' name, LINE, COL 
       FROM ALL_STATEMENTS
       WHERE OBJECT_NAME = 'P1'
      )
      START WITH USAGE_CONTEXT_ID = 0 AND OBJECT_NAME = 'P1'
      CONNECT BY PRIOR USAGE_ID = USAGE_CONTEXT_ID AND OBJECT_NAME = 'P1';
  USAGE_ID USAGES                                   LINE        COL
---------- ----------------------------------- ---------- ----------
          1 DECLARATION P1                              1         11
          2   DEFINITION P1                             1         11
          3     DECLARATION P_CUST_ID                   1         15
          4       REFERENCE NUMBER                      1         27
          5     DECLARATION P_CUST_NAME                 2         33
          6       REFERENCE VARCHAR2                    2         49
          7     SELECT STATEMENT                        5          5
          8       REFERENCE CUSTOMERS                   8         12
          9       REFERENCE P_CUST_ID                   9         26
         10       REFERENCE CUSTOMER_ID                 9         12
         11       REFERENCE CUSTOMERS                   6         20
         12       REFERENCE CUST_FIRST_NAME             5         20
         13       ASSIGNMENT P_CUST_NAME                7         12
SQL文のシグネチャについて

すべてのSQL文には、すべてのPL/SQLユニット内の文のインスタンスを識別する一意のPL/Scopeシグネチャがあります。

SQL文のシグネチャは、同じSQL_IDを使用するSQLのPL/SQLユニットからのコールと、他のPL/SQLユニットからの別のコールを区別します。

ネストされた副問合せは、ALL_STATEMENTS内の個別のSQL文ではありません。

例14-7 異なるPL/SQLユニットからコールされた場合の同じSQL文の個別のSQLシグネチャ

この例では、PROCEDURE p1およびp2からコールされたときの、同じSQL文の2つの異なるシグネチャを示しています。ネストされた副問合せに別のSQL_IDが割り当てられていないため、ALL_STATEMENTS内の個別のSQL文ではないことがわかります。

CREATE OR REPLACE PROCEDURE p1 (p_cust_id   NUMBER, 
                                p_cust_name OUT VARCHAR2) 
IS 
BEGIN 
    SELECT (SELECT CUST_FIRST_NAME 
            FROM   CUSTOMERS) 
    INTO   p_cust_name 
    FROM   CUSTOMERS 
    WHERE  CUSTOMER_ID = p_cust_id; 
END; 
/ 
CREATE OR REPLACE PROCEDURE P2 (p_cust_id   NUMBER, 
                                p_cust_name OUT VARCHAR2) 
IS 
BEGIN 
    SELECT (SELECT CUST_FIRST_NAME 
            FROM   CUSTOMERS) 
    INTO   p_cust_name 
    FROM   CUSTOMERS 
    WHERE  CUSTOMER_ID = p_cust_id; 
END; 
/ 

ACCEPT nam CHAR PROMPT "Enter OBJECT_NAME : "

SELECT * 
FROM   ALL_STATEMENTS
WHERE OBJECT_NAME = '&&nam'
ORDER BY LINE, COL;
P1とP2のALL_STATEMENTSを選択して、同じSQL_IDの別のSQLシグネチャを確認します。
new   3: WHERE OBJECT_NAME = 'P1'
OE
138835D3A2EBBA76A7A064E4DC14B466 SELECT
P1
PROCEDURE             7          5          5                2 c02b6yppqb46p NO  NO  NO  NO  NO  NO
YES SELECT (SELECT CUST_FIRST_NAME FROM CUSTOMERS) FROM CUSTOMERS WHERE CUSTOMER_ID   = :B1
SELECT (SELECT CUST_FIRST_NAME FROM CUSTOMERS) FROM CUSTOMERS WHERE CUSTOMER_ID      0


new   3: WHERE OBJECT_NAME = 'P2'
OE
E6A5E27E5E90997A169C5C25393FAB35 SELECT
P2
PROCEDURE             7          5          5                2 c02b6yppqb46p NO  NO  NO  NO  NO  NO
YES SELECT (SELECT CUST_FIRST_NAME FROM CUSTOMERS) FROM CUSTOMERS WHERE CUSTOMER_ID   = :B1
SELECT (SELECT CUST_FIRST_NAME FROM CUSTOMERS) FROM CUSTOMERS WHERE CUSTOMER_ID      0

SQL Developer

PL/ScopeはSQL Developerの機能の1つです。SQL DeveloperからのPL/Scopeの使用の詳細は、SQL Developerのオンライン・ヘルプを参照してください。

PL/SQLコードの管理に役立つデータ・ディクショナリ・ビューの概要

PL/Scopeデータ・ディクショナリ・ビューの他に、次に示す静的ディクショナリ・ビューがPL/SQLのプログラマにとって最も有用であり、PL/SQLコード管理レポートに関連する問合せで最も頻繁に参照されます。これは、すべての静的データ・ディクショナリ・ビューを網羅したリストではありません。

PL/SQLコードの管理に役立つデータ・ディクショナリ・ビューのサマリー

ビュー名 説明:
ALL_ARGUMENTS 現在のユーザーがアクセスできる関数およびプロシージャの引数をリストします
ALL_DEPENDENCIES 現在のユーザーがアクセスできるプロシージャ、パッケージ、関数、パッケージ本体およびトリガー間の依存関係を説明します。
ALL_ERRORS 現行のユーザーがアクセスできるストアド・オブジェクトでの現状のエラーを説明します
ALL_IDENTIFIERS 現行のユーザーがアクセスできるストアド・オブジェクトの識別子に関する情報を説明します
USER_OBJECT_SIZE 現行のユーザーが所有するPL/SQLオブジェクトのサイズ(バイト単位)を説明します。この情報はコンパイラとランタイム・エンジンで使用するものですが、この情報を使用すると、環境内の大きなプログラムを識別できます。
ALL_OBJECTS 現行ユーザーがアクセス可能なすべてのオブジェクトが表示されます。
ALL_PLSQL_OBJECT_SETTINGS 現行のユーザーがアクセスできるストアド・オブジェクトのコンパイラ設定の情報を説明します
ALL_PROCEDURES 現在のユーザーがアクセスできるすべてのPL/SQL関数とプロシージャ、および関連するプロパティを説明します
ALL_SEQUENCES 現行ユーザーがアクセス可能な順序を説明します
ALL_SOURCE 現行のユーザーがアクセスできるストアド・オブジェクトのテキスト・ソースを説明します
ALL_STATEMENTS ユーザーがアクセスできるストアドPL/SQLオブジェクト内のすべてのSQL文を説明します
ALL_STORED_SETTINGS 現行のユーザーが実行権限を持つストアドPL/SQLユニットの永続パラメータ設定を説明します
ALL_SYNONYMS 現行のユーザーがアクセスできるシノニムを説明します
ALL_TAB_COLUMNS 現行のユーザーがアクセスできる表、ビューおよびクラスタの列を説明します
ALL_TABLES 現行のユーザーがアクセスできるリレーショナル表を説明します
ALL_TRIGGERS 現行のユーザーがアクセスできる表のトリガーを説明します
ALL_VIEWS 現行のユーザーがアクセスできるビューを説明します

サンプルPL/Scopeセッション

次のサンプル・セッションでは、HRとしてログインしているものとします。

  1. セッション・パラメータを設定します。
    ALTER SESSION SET PLSCOPE_SETTINGS='IDENTIFIERS:ALL';
    
  2. 次のパッケージを作成します。
    CREATE OR REPLACE PACKAGE pack1 AUTHID DEFINER IS
      TYPE r1 is RECORD (rf1 VARCHAR2(10));
      FUNCTION f1(fp1 NUMBER) RETURN NUMBER;
      PROCEDURE p1(pp1 VARCHAR2);
    END PACK1;
    /
    CREATE OR REPLACE PACKAGE BODY pack1 IS
      FUNCTION f1(fp1 NUMBER) RETURN NUMBER IS
        a NUMBER := 10;
      BEGIN
        RETURN a;
      END f1;
      PROCEDURE p1(pp1 VARCHAR2) IS
        pr1 r1;
      BEGIN
        pr1.rf1 := pp1;
      END;
    END pack1;
    /
    
  3. PL/Scopeがそのパッケージ本体のすべての識別子を収集していることを確認します。
    SELECT PLSCOPE_SETTINGS
    FROM USER_PLSQL_OBJECT_SETTINGS
    WHERE NAME='PACK1' AND TYPE='PACKAGE BODY'
    

    結果:

    PLSCOPE_SETTINGS
    ------------------------------------------------------------------------
    IDENTIFIERS:ALL
    
  4. すべてのDECLARATIONの使用方法について問い合せ、HRの一意の識別子を表示します。たとえば、%1のような名前の一意の識別子をすべて確認するには、次のSQL*Plus書式設定コマンドと問合せを使用します。
    COLUMN NAME FORMAT A6
    COLUMN SIGNATURE FORMAT A32
    COLUMN TYPE FORMAT A9
    
    SELECT NAME, SIGNATURE, TYPE
    FROM USER_IDENTIFIERS
    WHERE NAME LIKE '%1' AND USAGE='DECLARATION'
    ORDER BY OBJECT_TYPE, USAGE_ID;
    

    結果は次のようになります。

    NAME   SIGNATURE                        TYPE
    ------ -------------------------------- ---------
    PACK1  41820FA4D5EF6BE707895178D0C5C4EF PACKAGE
    R1     EEBB6849DEE31BC77BF186EBAE5D4E2D RECORD
    RF1    41D70040337349634A7F547BC83517C7 VARIABLE
    F1     D51E825FF334817C977174423E3D0765 FUNCTION
    FP1    CAC3474C112DBEC67AB926978D9A16C1 FORMAL IN
    P1     B7C0576BA4D00C33A65CC0C64CADAB89 PROCEDURE
    PP1    6B74CF95A5B7377A735925DFAA280266 FORMAL IN
    FP1    98EB63B8A4AFEB5EF94D50A20165D6CC FORMAL IN
    PP1    62D8463A314BE1F996794723402278CF FORMAL IN
    PR1    BDB1CB26C97562CCC20CD1F32D341D7C VARIABLE
     
    10 rows selected.
    

    *_IDENTIFIERS静的データ・ディクショナリ・ビューでは、基本的な型名のみが表示されます。たとえば、ローカル変数やレコード・フィールドのTYPEVARIABLEです。VARIABLEの正確な型を確認するには、そのUSAGE_CONTEXT_IDを使用する必要があります。

  5. すべてのローカル変数を検索します。
    COLUMN VARIABLE_NAME FORMAT A13
    COLUMN CONTEXT_NAME FORMAT A12
    
    SELECT a.NAME variable_name,
            b.NAME context_name,
            a.SIGNATURE
    FROM USER_IDENTIFIERS a, USER_IDENTIFIERS b
    WHERE a.USAGE_CONTEXT_ID = b.USAGE_ID
    AND a.TYPE = 'VARIABLE'
    AND a.USAGE = 'DECLARATION'
    AND a.OBJECT_NAME = 'PACK1'
    AND a.OBJECT_NAME = b.OBJECT_NAME
    AND a.OBJECT_TYPE =  b.OBJECT_TYPE
    AND (b.TYPE = 'FUNCTION' or b.TYPE = 'PROCEDURE')
    ORDER BY a.OBJECT_TYPE, a.USAGE_ID;
    

    結果は次のようになります。

    VARIABLE_NAME CONTEXT_NAME SIGNATURE
    ------------- ------------ --------------------------------
    A             F1           1691C6B3C951FCAA2CBEEB47F85CF128
    PR1           P1           BDB1CB26C97562CCC20CD1F32D341D7C
     
    2 rows selected.
    
  6. ローカル変数Aに対して実行されたすべての使用方法を検索します。
    COLUMN USAGE FORMAT A11
    COLUMN USAGE_ID FORMAT 999
    COLUMN OBJECT_NAME FORMAT A11
    COLUMN OBJECT_TYPE FORMAT A12
    
    SELECT USAGE, USAGE_ID, OBJECT_NAME, OBJECT_TYPE
    FROM USER_IDENTIFIERS
    WHERE SIGNATURE='1691C6B3C951FCAA2CBEEB47F85CF128'  -- signature of A
    ORDER BY OBJECT_TYPE, USAGE_ID;
    

    結果:

    USAGE       USAGE_ID OBJECT_NAME OBJECT_TYPE
    ----------- -------- ----------- ------------
    DECLARATION        6 PACK1       PACKAGE BODY
    ASSIGNMENT         8 PACK1       PACKAGE BODY
    REFERENCE          9 PACK1       PACKAGE BODY
     
    3 rows selected.
    

    ローカル識別子Aに対して実行された使用方法は、識別子宣言(USAGE_ID 6)、代入(USAGE_ID 8)、および参照(USAGE_ID 9)です。

  7. ローカル識別子Aの宣言から、その型を調べます。
    COLUMN NAME FORMAT A6
    COLUMN TYPE FORMAT A15
    
    SELECT a.NAME, a.TYPE
    FROM USER_IDENTIFIERS a, USER_IDENTIFIERS b
    WHERE a.USAGE = 'REFERENCE'
    AND a.USAGE_CONTEXT_ID = b.USAGE_ID
    AND b.USAGE = 'DECLARATION'
    AND b.SIGNATURE = 'D51E825FF334817C977174423E3D0765'  -- signature of F1
    AND a.OBJECT_TYPE = b.OBJECT_TYPE
    AND a.OBJECT_NAME = b.OBJECT_NAME;
    

    結果:

    NAME   TYPE
    ------ ---------------
    NUMBER NUMBER DATATYPE
     
    1 row selected.
  8. ローカル識別子Aに対する代入が行われた場所を調べます。
    SELECT LINE, COL, OBJECT_NAME, OBJECT_TYPE
    FROM USER_IDENTIFIERS
    WHERE SIGNATURE='1691C6B3C951FCAA2CBEEB47F85CF128'  -- signature of A
    AND USAGE='ASSIGNMENT';
    

    結果:

          LINE        COL OBJECT_NAME OBJECT_TYPE
    ---------- ---------- ----------- ------------
             3          5 PACK1       PACKAGE BODY
     
    1 row selected.