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
識別子データがなくてもPL/Scopeを使用できます。このデータが必要となるのは、これらのパッケージで作成されるベース型またはサブプログラムがコードのどこで使用されるかを知る必要がある場合のみです。たとえば、ベース型BINARY_INTEGER
がコードのどこで使用されるかを確認する場合は、PLS_INTEGER
をかわりに使用できます。
新たに作成されたOracle 11.1.0.7データベースまたは10.2から11.1.0.7にアップグレードされたデータベースには、パッケージSTANDARD
およびDBMS_STANDARD
に対するPL/Scope識別子データが含まれます。11.1.0.6から11.1.0.7にアップグレードされたデータベースにはこのデータはありません。
データベースにこのデータが含まれるかどうかを確認するには、例12-1の問合せを使用します。
例12-1に、データベースにSTANDARD
およびDBMS_STANDARD
のPL/Scope識別子データがある場合の問合せの結果を示します。
例12-1 STANDARDおよびDBMS_STANDARDのPL/Scope識別子データの有無
問合せ:
COLUMN OBJECT_NAME FORMAT A14 SELECT UNIQUE OBJECT_NAME FROM ALL_IDENTIFIERS WHERE OBJECT_NAME IN ('STANDARD', 'DBMS_STANDARD') AND OWNER='SYS' ORDER BY OBJECT_NAME;
結果:
OBJECT_NAME -------------- DBMS_STANDARD STANDARD 2 rows selected.
例12-1の問合せで行が選択されない場合、データベースにはパッケージSTANDARD
およびDBMS_STANDARD
のPL/Scope識別子データがありません。このデータを収集するには、12.2.3項で説明するように、DBAがパッケージSTANDARD
およびDBMS_STANDARD
を再コンパイルする必要があります。
DBAは次の手順を使用して、パッケージSTANDARD
およびDBMS_STANDARD
を再コンパイルすることができます。
注意: この手順では、再コンパイルにより、データベース内のすべてのPL/SQLオブジェクトが無効化されてから再有効化されます。 |
データベースに接続し、データベースを停止してから、UPGRADE
モードで起動します。
CONNECT / AS SYSDBA; SHUTDOWN IMMEDIATE; STARTUP PFILE=parameter_initialization_file UPGRADE;
パッケージSTANDARD
およびDBMS_STANDARD
のすべての識別子のデータをPL/Scopeで収集します。
ALTER SESSION SET PLSCOPE_SETTINGS='IDENTIFIERS:ALL';
データベースを無効にして再コンパイルします。
@?/rdbms/admin/utlirp.sql
これで、PLSCOPE_SETTINGS='IDENTIFIERS:ALL'
を使用して再コンパイルされたSTANDARD
およびDBMS_STANDARD
を除いて、データベース内のすべてのPL/SQLオブジェクトが無効になります。
(オプション)PLSCOPE_SETTINGS='IDENTIFIERS:ALL'
を使用して再コンパイルするその他のPL/SQLオブジェクトを無効にします。これには、次のようなスクリプトを使用します。
この問合せの5から9行をカスタマイズして、PL/Scope識別子データを必要とするオブジェクトのみを無効にします。次のスクリプトではすべてのオブジェクトのすべての識別子が収集されるため、大容量のデータが生成され、コンパイルに時間がかかる場合があります。
DECLARE TYPE ObjIDArray IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; ObjIDs ObjIDArray; BEGIN SELECT object_id BULK COLLECT INTO ObjIDs FROM ALL_OBJECTS WHERE object_type IN (SELECT DISTINCT TYPE FROM ALL_PLSQL_OBJECT_SETTINGS); FOR i IN 1..SQL%ROWCOUNT LOOP BEGIN DBMS_UTILITY.INVALIDATE(ObjIDs(i), 'PLSCOPE_SETTINGS=IDENTIFIERS:ALL REUSE SETTINGS'); NULL; END; END LOOP; END; /
注意: このスクリプトでは次のことに注意してください。
|
データベースを停止してから、NORMAL
モードで起動します。
SHUTDOWN IMMEDIATE;
STARTUP PFILE=parameter_initialization_file;
無効なPL/SQLオブジェクトが残っている場合は、次のいずれかを実行します。
参照時に自動的に再コンパイルされるようにします。
(複雑な依存関係がある場合には時間がかかることがあります。)
12.2.4項で説明するように、スクリプトutlrp
.sql
を実行して、無効なPL/SQLオブジェクトを再コンパイルします。
データベースがNORMAL
モードで再起動されている場合(手順5)、DBAまたはDBAロールが付与されたユーザーは次の手順を使用できます。
SYS
としてデータベースに接続します。
CONNECT / AS SYS;
スクリプトutlrp
.sql
を実行します。
@?/rdbms/admin/utlrp.sql
スクリプトから指示がある場合はそれに従い、再びスクリプトを実行します。
指示がなくスクリプトが異常終了した場合は、再びスクリプトを実行します。
PL/ScopeのデータはSYSAUX
表領域に格納されます。SYSDBA
としてログオンしている場合は、例12-2の問合せを使用してPL/Scopeデータが使用している領域の容量を表示できます。
例12-2 PL/Scopeデータによる領域の使用量
問合せ:
SELECT SPACE_USAGE_KBYTES FROM V$SYSAUX_OCCUPANTS WHERE OCCUPANT_NAME='PL/SCOPE';
結果:
SPACE_USAGE_KBYTES ------------------ 1600 1 row selected.
SYSAUX
表領域の管理の詳細は、『Oracle Database管理者ガイド』を参照してください。
PL/Scopeで収集したデータを表示するには、次のいずれかを使用できます。
静的データ・ディクショナリ・ビュー*_IDENTIFIERS
では、その型や使用方法など、PL/Scope識別子に関する情報が表示されます。これらのビューの一般情報は、『Oracle Databaseリファレンス』を参照してください。
内容は次のとおりです。
*_IDENTIFIERS
ビューの各行は、PL/SQLユニットの識別子の一意の使用方法を表します。これらの各ビューでは、次のものがコンパイル・ユニット内で同等の一意キーです。
LINE
、COL
、USAGE
USAGE_ID
*_IDENTIFIERS
ビューの使用方法は、12.6項を参照してください。
注意: IN OUT モードでサブプログラムに渡される識別子では、*_IDENTIFIERS にREFERENCE 使用方法(IN に対応)およびASSIGNMENT 使用方法(OUT に対応)の2つの行があります。 |
コンテキストは、複数の使用方法の間の関係を検出する場合に役立ちます。最上位のスキーマ・オブジェクト宣言および定義を除き、識別子のすべての使用方法は別の使用方法のコンテキストで発生します。次に例を示します。
ローカル変数宣言は、最上位のプロシージャ宣言のコンテキスト内で発生します。
x
VARCHAR2(10)
など、識別子が変数として宣言される場合、VARCHAR2
型参照のUSAGE_CONTEXT_ID
には、x
宣言のUSAGE_ID
が挿入され、変数宣言をその型に関連付けることができます。
つまり、例12-3に示すように、USAGE_CONTEXT_ID
はUSAGE_ID
に対する再帰外部キーです。
例12-3 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 N............. variable assignment D............. constant reference 24 rows selected.
識別子のシグネチャは、プログラム・ユニット内および複数のプログラム・ユニット間で一意のものです。つまり、シグネチャは複数の識別子が同じ名前であっても、同じプログラム・ユニット内に定義されているか、または異なるプログラム・ユニットに定義されているかを区別します。
例12-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/ScopeはSQL Developerの機能の1つです。SQL DeveloperからのPL/Scopeの使用方法の詳細は、SQL Developerのオンライン・ヘルプまたはドキュメントを参照してください。
表12-1に、PL/Scopeが収集する識別子の型をアルファベット順に示します。表12-1の識別子の型は、*_IDENTIFIER
静的データ・ディクショナリ・ビューのTYPE
列に表示されます。このビューについては、『Oracle Databaseリファレンス』を参照してください。
注意: PLSCOPE_SETTINGS='IDENTIFIERS:ALL' でコンパイルされていないコンパイル・ユニットに宣言された識別子は、*_IDENTIFIER 静的データ・ディクショナリ・ビューに表示されません。 |
表12-1 PL/Scopeが収集する識別子の型
TYPE列の値 | コメント |
---|---|
|
|
|
|
|
|
|
各 |
|
|
|
|
|
|
|
|
|
イテレータは |
|
ラベル宣言もコンテキストとして機能します。 |
|
|
|
|
|
|
|
内部不透明型には |
|
|
|
|
|
|
|
|
|
|
|
PL/Scopeでは、シノニムのベース・オブジェクト名は解決しません。シノニムのベース・オブジェクト名を調べるには、 |
|
|
|
|
|
|
|
オブジェクト属性、ローカル変数、パッケージ変数、レコード・フィールドのいずれにもできます。 |
表12-2に、PL/Scopeがレポートする使用方法をアルファベット順に示します。表12-2の識別子の型は、*_IDENTIFIER
静的データ・ディクショナリ・ビューのUSAGE
列に表示されます。このビューについては、『Oracle Databaseリファレンス』を参照してください。
表12-2 PL/Scopeがレポートする使用方法
次のサンプル・セッションでは、HR
としてログインしているものとします。
セッション・パラメータを設定します。
ALTER SESSION SET PLSCOPE_SETTINGS='IDENTIFIERS:ALL';
次のパッケージを作成します。
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; /
PL/Scopeがそのパッケージ本体のすべての識別子を収集していることを確認します。
SELECT PLSCOPE_SETTINGS FROM USER_PLSQL_OBJECT_SETTINGS WHERE NAME='PACK1' AND TYPE='PACKAGE BODY'
結果:
PLSCOPE_SETTINGS ------------------------------------------------------------------------ IDENTIFIERS:ALL
すべての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
静的データ・ディクショナリ・ビューでは、基本的な型名のみが表示されます。たとえば、ローカル変数やレコード・フィールドのTYPE
はVARIABLE
です。VARIABLE
の正確な型を確認するには、そのUSAGE_CONTEXT_ID
を使用する必要があります。
すべてのローカル変数を検索します。
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.
ローカル変数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
)です。
ローカル識別子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.
注意: この問合せでは、パッケージSTANDARD およびDBMS_STANDARD のPL/Scope識別子データがデータベースに含まれる場合のみ、出力が表示されます。詳細は、第12.2項を参照してください。 |
ローカル識別子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.