PL/Scopeはコンパイラ駆動方式のツールであり、プログラム・ユニットのコンパイル時にPL/SQLソース・コード内の識別子に関するデータを収集し、静的データ・ディクショナリ・ビューで使用できるようにします。収集されたデータには識別子の型、使用方法(宣言、定義、参照、コール、代入)およびソース・コードにおける各使用場所に関する情報が含まれています。
PL/Scopeによって、強力で効率的なPL/Scopeソース・コード・ブラウザの開発が可能になります。このブラウザは、ソース・コードの参照および理解に費やされる時間を最小限にすることによって、PL/SQL開発者の生産性を向上させます。
PL/Scopeはアプリケーション開発者用のものであり、通常は開発データベースの環境で使用されます。
|
注意: PL/Scopeでは、ソース・コードがラップされているPL/SQLユニットのデータを収集できません。PL/SQLソース・コードのラップの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。 |
内容は次のとおりです。
デフォルトでは、PL/ScopeはPL/SQLソース・プログラムの識別子用のデータを収集しません。パッケージ本体にある識別子など、PL/SQLソース・プログラムのすべての識別子用のデータをPL/Scopeによって収集するには、PL/SQLコンパイル・パラメータPLSCOPE_SETTINGSを'IDENTIFIERS:ALL'に設定します。
|
注意: すべての識別子を収集すると大量のデータが生成され、コンパイル時間が長くなる可能性があります。 |
PL/Scopeでは、収集するデータをSYSAUX表領域に格納します。SYSAUX表領域が使用できず、PLSCOPE_SETTINGS='IDENTIFIERS:ALL'でプログラム・ユニットをコンパイルした場合、PL/Scopeではコンパイルされたオブジェクトのデータを収集しません。コンパイラから警告は発行されませんが、USER_ERRORS内に警告が保存されます。
|
関連項目:
|
パッケージSTANDARDおよびDBMS_STANDARDは、VARCHAR2やNUMBERなどのベース型と、RAISE_APPLICATION_ERRORなどのサブプログラムを宣言して定義します。データベースにこれらのパッケージのPL/Scope識別子データがある場合、これらのパッケージが作成する識別子の使用状況をPL/Scopeで追跡することができます。
STANDARDおよびDBMS_STANDARD識別子データの必要性
STANDARDおよびDBMS_STANDARD識別子データがなくてもPL/Scopeを使用できます。このデータが必要となるのは、これらのパッケージで作成されるベース型またはサブプログラムがコードのどこで使用されるかを知る必要がある場合のみです。たとえば、ベース型BINARY_INTEGERがコードのどこで使用されるかを確認する場合は、PLS_INTEGERをかわりに使用できます。
データベースでのSTANDARDおよびDBMS_STANDARD識別子データの有無
新たに作成されたOracle 11.1.0.7データベースまたは10.2から11.1.0.7にアップグレードされたデータベースには、パッケージSTANDARDおよびDBMS_STANDARDに対するPL/Scope識別子データが含まれます。11.1.0.6から11.1.0.7にアップグレードされたデータベースにはこのデータはありません。
データベースにこのデータが含まれるかどうかを確認するには、例8-1の問合せを使用します。
例8-1に、データベースにSTANDARDおよびDBMS_STANDARDのPL/Scope識別子データがある場合の問合せの結果を示します。
例8-1 STANDARDおよびDBMS_STANDARDのPL/Scope識別子データの有無
SQL> SELECT UNIQUE OBJECT_NAME FROM ALL_IDENTIFIERS 2 WHERE OBJECT_NAME IN ('STANDARD', 'DBMS_STANDARD') 3 AND OWNER='SYS'; OBJECT_NAME ------------------------------ DBMS_STANDARD STANDARD 2 rows selected. SQL>
例8-1の問合せで行が選択されない場合、データベースにはパッケージSTANDARDおよびDBMS_STANDARDのPL/Scope識別子データがありません。このデータを収集するには、「STANDARDおよびDBMS_STANDARDの再コンパイル」で説明するように、DBAがパッケージSTANDARDおよびDBMS_STANDARDを再コンパイルする必要があります。
STANDARDおよびDBMS_STANDARDの再コンパイル
DBAは次の手順を使用して、パッケージSTANDARDおよびDBMS_STANDARDを再コンパイルすることができます。
|
注意: この手順では、再コンパイルにより、データベース内のすべてのPL/SQLオブジェクトが無効化されてから再有効化されます。 |
データベースに接続し、データベースを停止してから、UPGRADEモードで起動します。
SQL> CONNECT / AS SYSDBA; SQL> SHUTDOWN IMMEDIATE; SQL> STARTUP PFILE=parameter_initialization_file UPGRADE;
パッケージSTANDARDおよびDBMS_STANDARDのすべての識別子のデータをPL/Scopeで収集します。
SQL> ALTER SESSION SET PLSCOPE_SETTINGS='IDENTIFIERS:ALL';
データベースを無効にして再コンパイルします。
SQL> @?/rdbms/admin/utlirp.sql
これで、PLSCOPE_SETTINGS='IDENTIFIERS:ALL'を使用して再コンパイルされたSTANDARDおよびDBMS_STANDARDを除いて、データベース内のすべてのPL/SQLオブジェクトが無効になります。
(オプション)PLSCOPE_SETTINGS='IDENTIFIERS:ALL'を使用して再コンパイルするその他のPL/SQLオブジェクトを無効にします。これには、次のようなスクリプトを使用します。
この問合せの5〜9行をカスタマイズして、PL/Scope識別子データを必要とするオブジェクトのみを無効にします。次のスクリプトではすべてのオブジェクトのすべての識別子が収集されるため、大容量のデータが生成され、コンパイルに時間がかかる場合があります。
SQL> DECLARE 2 TYPE ObjIDArray IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; 3 ObjIDs ObjIDArray; 4 BEGIN 5 SELECT object_id BULK COLLECT INTO ObjIDs 6 FROM ALL_OBJECTS 7 WHERE object_type IN 8 (SELECT DISTINCT TYPE 9 FROM ALL_PLSQL_OBJECT_SETTINGS); 10 FOR i IN 1..SQL%ROWCOUNT LOOP 11 BEGIN 12 DBMS_UTILITY.INVALIDATE(ObjIDs(i), 13 'PLSCOPE_SETTINGS=IDENTIFIERS:ALL REUSE SETTINGS'); 14 NULL; 15 END; 16 END LOOP; 17 END;
|
注意: このスクリプトでは次のことに注意してください。
|
データベースを停止してから、NORMALモードで起動します。
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP PFILE=parameter_initialization_file;
無効なPL/SQLオブジェクトが残っている場合は、次のいずれかを実行します。
PL/SQLオブジェクトの参照時に自動的に再コンパイルされるようにします。
(複雑な依存関係がある場合には時間がかかることがあります。)
「無効なPL/SQLオブジェクトを再コンパイルするutlrp.sqlの実行」で説明するように、スクリプトutlrp.sqlを実行して、無効なPL/SQLオブジェクトを再コンパイルします。
無効なPL/SQLオブジェクトを再コンパイルするutlrp.sqlの実行
データベースがNORMALモードで再起動されている場合(手順5)、DBAまたはDBAロールが付与されたユーザーは次の手順を使用できます。
PL/ScopeのデータはSYSAUX表領域に格納されます。SYSDBAとしてログオンしている場合は、例8-2の問合せを使用してPL/Scopeデータが使用している領域の容量を表示できます。
例8-2 PL/Scopeデータによる領域の使用量
SQL> SELECT SPACE_USAGE_KBYTES FROM V$SYSAUX_OCCUPANTS 2 WHERE OCCUPANT_NAME='PL/SCOPE'; SPACE_USAGE_KBYTES ------------------ 384 1 row selected. SQL>
SYSAUX表領域の管理の詳細は、『Oracle Database管理者ガイド』を参照してください。
PL/Scopeで収集したデータを表示するには、次のいずれかを使用できます。
静的データ・ディクショナリ・ビュー*_IDENTIFIERSでは、その型や使用方法など、PL/Scope識別子に関する情報が表示されます。これらのビューの一般情報は、『Oracle Databaseリファレンス』を参照してください。
内容は次のとおりです。
*_IDENTIFIERSビューの各行は、PL/SQLユニットの識別子の一意の使用方法を表します。これらの各ビューでは、次のものがコンパイル・ユニット内で同等の一意キーです。
LINE、COL、USAGE
USAGE_ID
*_IDENTIFIERSビューの使用方法は、「PL/Scopeがレポートする使用方法」を参照してください。
|
注意: IN OUTモードでサブプログラムに渡される識別子では、*_IDENTIFIERSにREFERENCE使用方法(INに対応)およびASSIGNMENT使用方法(OUTに対応)の2つの行があります。 |
コンテキストは、複数の使用方法の間の関係を検出する場合に役立ちます。最上位のスキーマ・オブジェクト宣言および定義を除き、識別子のすべての使用方法は別の使用方法のコンテキストで発生します。次に例を示します。
ローカル変数宣言は、最上位のプロシージャ宣言のコンテキスト内で発生します。
x VARCHAR2(10)など、識別子が変数として宣言される場合、VARCHAR2型参照のUSAGE_CONTEXT_IDには、x宣言のUSAGE_IDが挿入され、変数宣言をその型に関連付けることができます。
つまり、例8-3に示すように、USAGE_CONTEXT_IDはUSAGE_IDに対する再帰外部キーです。
例8-3 USAGE_CONTEXT_IDおよびUSAGE_ID
ALTER SESSION SET PLSCOPE_SETTINGS = 'IDENTIFIERS:ALL';
CREATE OR REPLACE PROCEDURE a (p1 IN BOOLEAN) 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) 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
P3.............. formal in out declaration
N............... variable declaration
Q............... variable declaration
Q............. variable assignment
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
N............. variable assignment
D............. constant reference
識別子のシグネチャは、プログラム・ユニット内および複数のプログラム・ユニット間で一意のものです。つまり、シグネチャは複数の識別子が同じ名前であっても、同じプログラム・ユニット内に定義されているか、または異なるプログラム・ユニットに定義されているかを区別します。
例8-4のプログラム・ユニットの場合、pという名前の2つの識別子があり、静的データ・ディクショナリ・ビューUSER_IDENTIFIERSにNAMEがpという行が複数ありますが、これらの行のSIGNATUREは異なるものです。外部プロシージャpに関連付けられた行に1つのシグネチャがあり、内部プロシージャpに関連付けられた行には別のシグネチャがあります。プログラム・ユニットqがプロシージャpをコールする場合、qのUSER_IDENTIFIERSビューには、NAMEがpでSIGNATUREが外部プロシージャpのシグネチャの行があります。
$ORACLE_HOME/plsql/demo/plscopedemo.sqlは、PL/SQL Web Toolkitを使用するPL/SQL Webアプリケーションとして実装されたHTMLベースのデモです。PL/SQL Webアプリケーションの詳細は、「PL/SQL Webアプリケーションの実装」を参照してください。
PL/ScopeはSQL Developerの機能の1つです。SQL DeveloperからのPL/Scopeの使用の詳細は、SQL Developerのオンライン・マニュアルを参照してください。
表8-1に、PL/Scopeが収集する識別子の型をアルファベット順に示します。表8-1の識別子の型は、*_IDENTIFIER静的データ・ディクショナリ・ビューのTYPE列に表示されます。このビューについては、『Oracle Databaseリファレンス』を参照してください。
|
注意: PLSCOPE_SETTINGS='IDENTIFIERS:ALL'でコンパイルされていないコンパイル・ユニットに宣言された識別子は、*_IDENTIFIER静的データ・ディクショナリ・ビューに表示されません。 |
表8-1 PL/Scopeが収集する識別子の型
| TYPE列の値 | コメント |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
各 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
イテレータは |
|
|
ラベル宣言もコンテキストとして機能します。 |
|
|
|
|
|
|
|
|
|
|
|
内部不透明型には |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PL/Scopeでは、シノニムのベース・オブジェクト名は解決しません。シノニムのベース・オブジェクト名を調べるには、 |
|
|
|
|
|
|
|
|
|
|
|
オブジェクト属性、ローカル変数、パッケージ変数、レコード・フィールドのいずれにもできます。 |
表8-2に、PL/Scopeがレポートする使用方法をアルファベット順に示します。表8-2の識別子の型は、*_IDENTIFIER静的データ・ディクショナリ・ビューのUSAGE列に表示されます。このビューについては、『Oracle Databaseリファレンス』を参照してください。
表8-2 PL/Scopeがレポートする使用方法
サンプルPL/Scopeセッションでは、次のPL/SQLプロシージャexample.sqlを使用しています。
CREATE OR REPLACE PACKAGE PACK1 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;
/
次のサンプル・セッションでは、HRとしてログインしているものとします。
セッション・パラメータを設定します。
SQL> ALTER SESSION SET PLSCOPE_SETTINGS='IDENTIFIERS:ALL';
PL/SQLプロシージャexample.sqlをコンパイルします。
SQL> @example.sql
PL/Scopeがそのパッケージ本体のすべての識別子を収集していることを確認します。
SQL> SELECT PLSCOPE_SETTINGS
FROM USER_PLSQL_OBJECT_SETTINGS
WHERE NAME='PACK1' AND TYPE='PACKAGE BODY'
PLSCOPE_SETTINGS
----------------
IDENTIFIERS:ALL
すべてのDECLARATIONの使用方法について問い合せ、HRの一意の識別子を表示します。たとえば、%1のような名前の一意の識別子をすべて確認するには、次の問合せを使用します。
SQL> 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 EEFCF8352A41F4F264B4EF20D7F63A74 FUNCTION FP1 70648EC9E1C3C7FA10C0AE6415FAEC3B FORMAL IN P1 0BE2106B9EFA719D49AF60965EBD69AE PROCEDURE PP1 85B6C0F3BBA39185B00465082322444B FORMAL IN FP1 771368AE41084ADD477DE62A7B1D4278 FORMAL IN PP1 D98482491487F39B4CBC8B776130B739 FORMAL IN PR1 174C2528B929953F4FE2A43DEBA2B5D0 VARIABLE P1 3D1CA191D63523E40E25A72D89424324 FORMAL IN
*_IDENTIFIERS静的データ・ディクショナリ・ビューでは、基本的な型名のみが表示されます。たとえば、ローカル変数やレコード・フィールドのTYPEはVARIABLEです。VARIABLEの正確な型を確認するには、そのUSAGE_CONTEXT_IDを使用する必要があります。
すべてのローカル変数を検索します。
SQL> 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 2268998957D20FACD63493B7A77BC55B
PR1 P1 174C2528B929953F4FE2A43DEBA2B5D0
ローカル変数Aに対して実行されたすべての使用方法を検索します。
SQL> SELECT USAGE, USAGE_ID, OBJECT_NAME, OBJECT_TYPE
FROM USER_IDENTIFIERS
WHERE SIGNATURE='2268998957D20FACD63493B7A77BC55B'
ORDER BY OBJECT_TYPE, USAGE_ID;
USAGE USAGE_ID OBJECT_NAME OBJECT_TYPE
------------------------------------------------------
DECLARATION 4 PACK1 PACKAGE BODY
ASSIGNMENT 5 PACK1 PACKAGE BODY
REFERENCE 6 PACK1 PACKAGE BODY
ローカル識別子Aに対して実行された使用方法は、識別子宣言(USAGE_ID 6)、代入(USAGE_ID 8)、および参照(USAGE_ID 9)です。
ローカル識別子Aの宣言から、その型を調べます。
SQL> 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 = '2268998957D20FACD63493B7A77BC55B'
AND a.OBJECT_TYPE = b.OBJECT_TYPE
AND a.OBJECT_NAME = b.OBJECT_NAME;
NAME TYPE
--------------------------------
NUMBER DATATYPE STANDARD
|
注意: この問合せでは、パッケージSTANDARDおよびDBMS_STANDARDのPL/Scope識別子データがデータベースに含まれる場合のみ、出力が表示されます。詳細は、「STANDARDおよびDBMS_STANDARDのPL/Scope識別子データ」を参照してください。 |
ローカル識別子Aに対する代入が行われた場所を調べます。
SQL> SELECT LINE, COL, OBJECT_NAME, OBJECT_TYPE
FROM USER_IDENTIFIERS
WHERE SIGNATURE='666CEC3A2180DF4013CEBE330A8CE747'
AND USAGE='ASSIGNMENT';
LINE COL OBJECT_NAME OBJECT_TYPE
------------------------------------------------
3 7 PACK1 PACKAGE BODY