| Oracle Database PL/SQLユーザーズ・ガイドおよびリファレンス 10g リリース2(10.2) B19257-01 |
|
この付録では、スタンドアロンのwrapユーティリティおよびDBMS_DDLパッケージのサブプログラムを使用して、PL/SQLのソース・コードを不明瞭化(ラップ)する方法について説明します。PL/SQLユニットを不明瞭化(隠ぺい)すると、ソース・コードおよび実装の詳細を隠したままPL/SQLアプリケーションを配布できます。
この付録の項目は、次のとおりです。
PL/SQLユニットの不明瞭化(ラップ)とは、PL/SQLのソース・コードを隠す処理のことです。ラップを行うには、wrapユーティリティおよびDBMS_DDLサブプログラムを使用します。コマンドラインから実行するwrapユーティリティによって、SQL*Plusのインストール・スクリプトなどの入力SQLファイルが処理されます。DBMS_DDLサブプログラムでは、単一のCREATE PROCEDUREコマンドなど、動的に生成された単一のPL/SQLユニットがラップされます。
wrapユーティリティまたはDBMS_DDLパッケージのラップ・サブプログラムを使用してPL/SQLユニットのソース・コードを不明瞭化(隠ぺい)すると、次の利点があります。
USER_SOURCE、ALL_SOURCEまたはDBA_SOURCEデータ・ディクショナリ・ビューから参照されません。
PL/SQLユニットを不明瞭化(ラップ)する場合は、次のことに注意してください。
PL/SQLのソース・コードを不明瞭化する場合には、次の制限があります。
wrapユーティリティで処理されたファイルは、リリース8.1.6のOracleデータベースにロードできますが、リリース8.1.6のwrapユーティリティで処理されたファイルは、リリース8.1.5のOracleデータベースにロードできません。
DEFINE表記法を使用して置換変数を含めることはできません。他の不明瞭化しないSQL文では、置換変数を使用できます。
DBMS_DDL.WRAPの出力でDBMS_SQL.PARSEを起動する場合(32767バイトを超えるテキストに対する文の仮パラメータのデータ型がVARCHAR2AまたはVARCHAR2Sであるオーバーロードを使用するとき)は、LFFLGパラメータにFALSEを設定する必要があります。設定しないと、DBMS_SQL.PARSEによって、ラップされたユニットに改行が追加されるため、ユニットが破損します。
wrapユーティリティでは、入力SQLファイルが処理されて、パッケージ仕様部、パッケージ本体、ファンクション、プロシージャ、型仕様部、型本体など、ファイル内のPL/SQLユニットのみが不明瞭化されます。無名ブロックのPL/SQLコンテンツ、トリガーまたはPL/SQL以外のコードは不明瞭化されません。
wrapユーティリティを実行するには、次の構文を使用して、オペレーティング・システム・プロンプトでwrapコマンドを入力します。
wrap iname=input_file [oname=output_file]
等号の前後には空白を使用しないでください。
input_fileは、通常、SQL*Plusを使用して実行する、SQL文を含むファイルの名前です。ファイル拡張子を省略すると、拡張子は.sqlであるとみなされます。たとえば、次のコマンドは同じ意味を持ちます。
次のように、異なるファイル拡張子を指定することもできます。
wrap iname=/mydir/myfile.src
output_fileは、作成するファイル(不明瞭化されたファイル)の名前です。onameは任意に指定します。出力ファイル名はデフォルトで入力ファイルの名前となり、拡張子はデフォルトで.plbとなります。たとえば、次のコマンドは同じ意味を持ちます。
次に示すように、onameオプションを使用して、異なるファイル名と拡張子を指定できます。
wrap iname=/mydir/myfile oname=/yourdir/yourfile.out
入力ファイルでは、SQL文を任意に組み合せることができます。ほとんどの文はそのままの形で渡されます。サブプログラム、パッケージまたはオブジェクト型を定義するCREATE文は、不明瞭化されます。これらの文の本体は、隠ぺいされた(ただしPL/SQLコンパイラが理解可能な)形式に置き換えられます。
次のCREATE文は不明瞭化されます。
CREATE [OR REPLACE] FUNCTION function_name
CREATE [OR REPLACE] PROCEDURE procedure_name
CREATE [OR REPLACE] PACKAGE package_name
CREATE [OR REPLACE] PACKAGE BODY package_name
CREATE [OR REPLACE] TYPE type_name AS OBJECT
CREATE [OR REPLACE] TYPE type_name UNDER type_name
CREATE [OR REPLACE] TYPE BODY type_name
CREATE [OR REPLACE] TRIGGER文および[DECLARE] BEGIN..END無名ブロックは不明瞭化されません。その他のSQL文はすべて、そのままの形で出力ファイルに渡されます。
CREATE OR REPLACEヘッダー内のコメント行およびC形式のコメント(/* */で区切られる)を除いて、ラップされるユニットのすべてのコメント行が削除されます。
出力ファイルはテキスト・ファイルです。このファイルをSQL*Plusでスクリプトとして実行し、PL/SQLプロシージャ、ファンクションおよびパッケージを設定できます。ラップされたファイルは、次のように実行します。
SQL> @wrapped_file_name.plb;
たとえば、wrap_test.sqlファイルの内容が次のとおりであるとします。
CREATE PROCEDURE wraptest IS TYPE emp_tab IS TABLE OF employees%ROWTYPE INDEX BY PLS_INTEGER; all_emps emp_tab; BEGIN SELECT * BULK COLLECT INTO all_emps FROM employees; FOR i IN 1..10 LOOP DBMS_OUTPUT.PUT_LINE('Emp Id: ' || all_emps(i).employee_id); END LOOP; END; /
ファイルをラップするには、オペレーティング・システム・プロンプトで次のように実行します。
wrap iname=wrap_test.sql
wrapユーティリティの出力は、次のようになります。
PL/SQL Wrapper: Release 10.2.0.0.0 on Tue Apr 26 16:47:39 2005
Copyright (c) 1993, 2005, Oracle.All rights reserved.
Processing wrap_test.sql to wrap_test.plb
wrap_test.plbテキスト・ファイルの内容を確認すると、1行目にCREATE PROCEDURE wraptest wrappedが表示され、ファイルの残りの内容は表示されません。
SQL*Plusでwrap_test.plbを実行し、ファイルのSQL文を実行するには、次のように入力します。
SQL> @wrap_test.plb
wrap_test.plbを実行した後、作成されたプロシージャを実行できます。
SQL> CALL wraptest();
DBMS_DDLパッケージには、パッケージ仕様部、パッケージ本体、ファンクション、プロシージャ、型仕様部、型本体など、単一のPL/SQLユニットを不明瞭化するプロシージャが含まれます。オーバーロードされるこれらのサブプログラムには、データベースに作成される動的生成PL/SQLプログラム・ユニットを不明瞭化するメカニズムが備えられています。
DBMS_DDLパッケージには、WRAPファンクションおよびCREATE_WRAPPEDプロシージャが含まれます。CREATE_WRAPPEDでは、テキストのラップおよびPL/SQLユニットの作成の両方が行われます。名前の競合および他のユーザがDBMS_DDLというローカル・パッケージを作成していたり、DBMS_DDLパブリック・シノニムを定義している場合の危険性を回避するために、ラップ・プロシージャをコールする場合は、パッケージの完全修飾名SYS.DBMS_DDLを使用してください。入力CREATE OR REPLACE文は、DBMS_DDL.WRAP()またはDBMS_DDL.CREATE_WRAPPED()を起動するユーザーの権限で実行されます。
また、DBMS_DDLパッケージには、ラップ・プロシージャへの入力が有効なPL/SQLユニットでない場合に発生するMALFORMED_WRAP_INPUT例外(ORA-24230)も含まれます。
例A-1に、CREATE_WRAPPEDを使用して、データベースにパッケージ仕様部およびパッケージ本体を動的に作成およびラップする方法を示します。
DECLARE -- the package_text variable contains the text to create the package spec and body package_text VARCHAR2(32767); FUNCTION generate_spec (pkgname VARCHAR2) RETURN VARCHAR2 AS BEGIN RETURN 'CREATE PACKAGE ' || pkgname || ' AS PROCEDURE raise_salary (emp_id NUMBER, amount NUMBER); PROCEDURE fire_employee (emp_id NUMBER); END ' || pkgname || ';'; END generate_spec; FUNCTION generate_body (pkgname VARCHAR2) RETURN VARCHAR2 AS BEGIN RETURN 'CREATE PACKAGE BODY ' || pkgname || ' AS PROCEDURE raise_salary (emp_id NUMBER, amount NUMBER) IS BEGIN UPDATE employees SET salary = salary + amount WHERE employee_id = emp_id; END raise_salary; PROCEDURE fire_employee (emp_id NUMBER) IS BEGIN DELETE FROM employees WHERE employee_id = emp_id; END fire_employee; END ' || pkgname || ';'; END generate_body; BEGIN package_text := generate_spec('emp_actions'); -- generate package spec SYS.DBMS_DDL.CREATE_WRAPPED(package_text); -- create and wrap the package spec package_text := generate_body('emp_actions'); -- generate package body SYS.DBMS_DDL.CREATE_WRAPPED(package_text); -- create and wrap the package body END; / -- call a procedure from the wrapped package CALL emp_actions.raise_salary(120, 100);
*_SOURCEビューを表示しても、ソースがラップされている(表示されない)ため、他のユーザーはコードの詳細を見ることができません。次に例を示します。
SELECT text FROM USER_SOURCE WHERE name = 'EMP_ACTIONS';
出力結果は、次のようになります。
|
![]() Copyright © 2005 Oracle Corporation. All Rights Reserved. |
|