次の任意のストアドPL/SQLユニットのPL/SQLソース・テキストをラップすることによって、他のユーザーが静的データ・ディクショナリ・ビュー*_SOURCE
を使用して、他のユーザーがそのテキストを表示することを防止できます。
パッケージ仕様部
パッケージ本体
型仕様部
型本体
ファンクション
プロシージャ
注意:
テキストのラップのセキュリティは高くありません。高いセキュリティを確保するには、Oracle Database Vaultを使用してください(『Oracle Database Vault管理者ガイド』を参照)。
ラップされたPL/SQLソース・テキストが含まれるファイルは、ラップされたファイルと呼ばれます。ラップされたファイルは、SQL*Plusによって、またはインポート・ユーティリティおよびエクスポート・ユーティリティによって移動、バックアップまたは処理できます。
ラップされたファイルを生成するには、PL/SQLラッパー・ユーティリティまたはDBMS_DDL
サブプログラムを使用します。PL/SQLラッパー・ユーティリティは、指定のSQLファイルによって作成されたすべてのラップ可能PL/SQLユニットのソース・テキストをラップします。DBMS_DDL
サブプログラムは、動的に生成された単一のラップ可能PL/SQLユニットのソース・テキストをラップします。
PL/SQLラッパー・ユーティリティおよびDBMS_DDL
サブプログラムでは、トークン化エラー(文字列の欠落など)は検出されますが、構文エラーやセマンティック・エラー(表やビューが存在しないなど)は検出されません。
12.1 PL/SQLコンパイラは、デフォルトで、9.2 PL/SQLコンパイラでコンパイルされているラップされたパッケージを使用できます。12.1 PL/SQLコンパイラが9.2 PL/SQLコンパイラでコンパイルされているラップされたパッケージを使用できないようにするには、PL/SQLコンパイル・パラメータPERMIT_92_WRAP_FORMAT
をFALSE
に設定します。PERMIT_92_WRAP_FORMAT
の詳細は、『Oracle Databaseリファレンス』を参照してください。PL/SQLのコンパイル・パラメータの詳細は、「PL/SQLユニットおよびコンパイル・パラメータ」を参照してください。
ここでのトピック
ラップされたファイルは、Oracle Databaseリリース間での下位互換性がありません。
たとえば、バージョンn.1 PL/SQL Wrapperユーティリティにより生成されたファイルをバージョン(n-1).2 Oracle Databaseにロードすることはできません。また、バージョンn.2 PL/SQL Wrapperユーティリティにより生成されたファイルをバージョンn.1 Oracle Databaseにロードすることもできません。ラップされたファイルは、パッチセット間で上位および下位の両方の互換性があります。
PL/SQLソース・テキストのラップは、パスワードや表名を隠すための安全な方法とはいえません。
高いセキュリティを確保するには、Oracle Database Vaultを使用してください(『Oracle Database Vault管理者ガイド』を参照)。
トリガーのPL/SQLソース・テキストは、ラップできません。
トリガーの実装の詳細を隠すには、実装の詳細をストアド・サブプログラムに配置し、そのサブプログラムをラップして、そのサブプログラムを起動する1行トリガーを記述します。
パッケージまたは型の仕様部ではなく、本体のみをラップします。
仕様部をラップしないことで、他の開発者は、パッケージまたは型を使用するために必要な情報を見ることができます(例A-5を参照)。本体はラップされているため、パッケージまたは型の実装は、他の開発者から隠されます。
ファイルの編集が完了した後にのみ、ファイルをラップします。
ラップされたファイルは、編集できません。ラップされたファイルの変更が必要な場合、ラップされていない元のファイルを編集し、再度ラップする必要があります。
ラップされたファイルを配布する前に、テキスト・エディタで表示して重要な部分がすべてラップされていることを確認します。
注意:
PL/SQLラッパー・ユーティリティは、バージョン10以降を使用することをお薦めします。
PL/SQLラッパー・ユーティリティは、単一のSQLファイル(SQL*Plusスクリプトなど)を取得して、各ラップ可能PL/SQLユニットのPL/SQLソース・テキストがラップされた同等のテキスト・ファイルを生成します。(ラップ可能PL/SQLユニットのリストは、「PL/SQLのソース・テキストのラップ」の概要を参照してください。)
PL/SQLラッパー・ユーティリティは、Oracle Databaseに接続できません。PL/SQLラッパー・ユーティリティを実行するには、オペレーティング・システム・プロンプトで(等号の前後に空白を入れずに)次のコマンドを入力します。
wrap iname=input_file [ oname=output_file ]
input_file
は、複数のSQL文の任意の組合せを含む既存のファイルの名前です。output_file
は、PL/SQLラッパー・ユーティリティによって作成されるファイル(ラップされたファイル)の名前です。
注意:
output_file
は、SQL*PlusではなくPL/SQLコンパイラによって解析されるため、input_file
にSQL*PlusのDEFINE
表記法で指定された置換変数を含めることはできません。
PL/SQLラッパー・ユーティリティは、ラップされたファイルから、次のコメントを除くすべてのコメントを削除します。
CREATE
文のヘッダー内のコメント(『Oracle Database SQL言語リファレンス』の構文図にあるCREATE
とplsql_source
の間)
/*
および*/
で区切られたコメント
注意:
input_file
がラップされたファイルの場合、input_file
とoutput_file
の内容は同じになります。
input_file
のデフォルトのファイル拡張子は、sql
です。output_file
のデフォルト名は、input_file
.plb
です。したがって、次のコマンドは同じ意味を持ちます。
wrap iname=/mydir/myfile wrap iname=/mydir/myfile.sql oname=/mydir/myfile.plb
次の例では、input_file
に異なるファイル拡張子を指定し、output_file
に異なる名前を指定します。
wrap iname=/mydir/myfile.src oname=/yourdir/yourfile.out
output_file
は、SQL*Plusのスクリプトとして実行できます。次に例を示します。
SQL> @myfile.plb;
例A-1に、2つのラップ可能PL/SQLユニット(プロシージャwraptest
およびファンクションfibonacci
)を含むSQLファイルwraptest2.sql
のテキストを示します。このファイルには、2つのコメントと、SQLのSELECT
文も含まれます。
例A-2では、PL/SQLラッパー・ユーティリティを使用してwraptest2.sql
をラップし、そのラップされたファイルwraptest2.plb
を表示します。ラップされたファイルでは、ユーティリティによって--
で始まるコメントが削除され、プロシージャwraptest
およびファンクションfibonacci
のPL/SQLソース・テキストがラップされた(判読不可能にされた)ことがわかりますが、SELECT
文や、/*
および*/
で区切られたコメントは変更されていません。
例A-3では、ラップされたファイルwraptest.plb
をSQL*Plusで実行し、プロシージャwraptest
およびファンクションfibonacci
を作成します。各サブプログラムのテキスト(ラップされているため判読不可能)を選択し、その後、サブプログラムを起動します。
例A-1 2つのラップ可能PL/SQLユニットを含むSQLファイル
-- The following statement will not change. This comment will be deleted. SELECT COUNT(*) FROM EMPLOYEES / /* The PL/SQL source text of the following two CREATE statements will be wrapped. This commment will not be deleted. */ CREATE PROCEDURE wraptest AUTHID CURRENT_USER 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; / CREATE OR REPLACE FUNCTION fibonacci ( n PLS_INTEGER ) RETURN PLS_INTEGER AUTHID CURRENT_USER IS fib_1 PLS_INTEGER := 0; fib_2 PLS_INTEGER := 1; BEGIN IF n = 1 THEN -- terminating condition RETURN fib_1; ELSIF n = 2 THEN RETURN fib_2; -- terminating condition ELSE RETURN fibonacci(n-2) + fibonacci(n-1); -- recursive invocations END IF; END; /
例A-2 PL/SQLラッパー・ユーティリティによるファイルのラップ
オペレーティング・システム・プロンプトが>
であると仮定。ファイルwraptest.sql
のラップ:
> wrap iname=wraptest2.sql
結果:
PL/SQL Wrapper: Release 12.1.0.1.0- 64bit Production on Fri Oct 5 09:04:47 2012 Copyright (c) 1993, 2009, Oracle. All rights reserved. Processing wraptest2.sql to wraptest2.plb
wraptest.plb
の内容:
SELECT COUNT(*) FROM EMPLOYEES / /* The PL/SQL source text of the following two CREATE statements will be wrapped. This commment will not be deleted. */ CREATE PROCEDURE wraptest wrapped a000000 1 abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd 7 12e 13c Ati2yLD3B+kU7XM0TVryX73L8xowg+lKLgwdNXRAAJn5B/5mc1dWMyeu2toxe3WQdE43ud4v iswWo6UlLCCfDjMv8TRCThSol2dhohW7/sYpz+StjJY6lZN0bGCbvqei89EAaB1Cyzbs5tft zL3sdcqGUS1Hoil/l7rHrSAppMlgj8OQcvUOUw8EAMdcEhWUGuVr1k7ZfPPryC0CPuQYNVMN RdHE7X+X9dq0dYx9Bydq4h6frnD3S4WpKl7lCcAWvutNino76tIyrPjP1J6c2SS/zd9VjaOQ VSF8QgURgxG+nfgdNIjcpg== / CREATE OR REPLACE FUNCTION fibonacci wrapped a000000 1 abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd 8 15b ff zJS4sutKjJStYT2YsGf4Mfh8YOowgxDc7Z7WfC+5Vs7LeMVjaYLf9VAw/DdubCQDVGuPJby1 PNujEYJ17ueaqoZUk6sEHNlzgW6LQjdWLqYESO2I9GJhTesUW/A8KedikM1NOUOgYGGMgvsU tuSyXAsICkDZlP+bDPR1xXpcOAx2jnfOP9A3zcg4/mzufgU8/w3hEgMB4yrv8AHmuReSpl8u HZzyzNRJ92oIKBbAOlJSzcT4RPnvKCA3uvKS /
例A-3 ラップされたファイルの実行およびラップされたPL/SQLユニットの表示
SQL> -- Run wrapped file: SQL> SQL> @wraptest2.plb SQL> SELECT COUNT(*) FROM EMPLOYEES 2 / COUNT(*) ---------- 107 1 row selected. SQL> /* The PL/SQL source text of the following two CREATE statements SQL> will be wrapped. This commment will not be deleted. */ SQL> CREATE PROCEDURE wraptest wrapped 2 a000000 3 1 4 abcd 5 abcd 6 abcd 7 abcd 8 abcd 9 abcd 10 abcd 11 abcd 12 abcd 13 abcd 14 abcd 15 abcd 16 abcd 17 abcd 18 abcd 19 7 20 12e 13c 21 Ati2yLD3B+kU7XM0TVryX73L8xowg+lKLgwdNXRAAJn5B/5mc1dWMyeu2toxe3WQdE43ud4v 22 iswWo6UlLCCfDjMv8TRCThSol2dhohW7/sYpz+StjJY6lZN0bGCbvqei89EAaB1Cyzbs5tft 23 zL3sdcqGUS1Hoil/l7rHrSAppMlgj8OQcvUOUw8EAMdcEhWUGuVr1k7ZfPPryC0CPuQYNVMN 24 RdHE7X+X9dq0dYx9Bydq4h6frnD3S4WpKl7lCcAWvutNino76tIyrPjP1J6c2SS/zd9VjaOQ 25 VSF8QgURgxG+nfgdNIjcpg== 26 27 / Procedure created. SQL> CREATE OR REPLACE FUNCTION fibonacci wrapped 2 a000000 3 1 4 abcd 5 abcd 6 abcd 7 abcd 8 abcd 9 abcd 10 abcd 11 abcd 12 abcd 13 abcd 14 abcd 15 abcd 16 abcd 17 abcd 18 abcd 19 8 20 15b ff 21 zJS4sutKjJStYT2YsGf4Mfh8YOowgxDc7Z7WfC+5Vs7LeMVjaYLf9VAw/DdubCQDVGuPJby1 22 PNujEYJ17ueaqoZUk6sEHNlzgW6LQjdWLqYESO2I9GJhTesUW/A8KedikM1NOUOgYGGMgvsU 23 tuSyXAsICkDZlP+bDPR1xXpcOAx2jnfOP9A3zcg4/mzufgU8/w3hEgMB4yrv8AHmuReSpl8u 24 HZzyzNRJ92oIKBbAOlJSzcT4RPnvKCA3uvKS 25 26 / Function created. SQL> SQL> -- Try to display procedure source text: SQL> SQL> SELECT text FROM USER_SOURCE WHERE name='WRAPTEST'; TEXT -------------------------------------------------------------------------------- PROCEDURE wraptest wrapped a000000 1 abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd 7 12e 13c Ati2yLD3B+kU7XM0TVryX73L8xowg+lKLgwdNXRAAJn5B/5mc1dWMyeu2toxe3WQdE43ud4v iswWo6UlLCCfDjMv8TRCThSol2dhohW7/sYpz+StjJY6lZN0bGCbvqei89EAaB1Cyzbs5tft zL3sdcqGUS1Hoil/l7rHrSAppMlgj8OQcvUOUw8EAMdcEhWUGuVr1k7ZfPPryC0CPuQYNVMN RdHE7X+X9dq0dYx9Bydq4h6frnD3S4WpKl7lCcAWvutNino76tIyrPjP1J6c2SS/zd9VjaOQ VSF8QgURgxG+nfgdNIjcpg== 1 row selected. SQL> SQL> -- Try to display function source text: SQL> SQL> SELECT text FROM USER_SOURCE WHERE name='FIBONACCI'; TEXT -------------------------------------------------------------------------------- FUNCTION fibonacci wrapped a000000 1 abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd 8 15b ff zJS4sutKjJStYT2YsGf4Mfh8YOowgxDc7Z7WfC+5Vs7LeMVjaYLf9VAw/DdubCQDVGuPJby1 PNujEYJ17ueaqoZUk6sEHNlzgW6LQjdWLqYESO2I9GJhTesUW/A8KedikM1NOUOgYGGMgvsU tuSyXAsICkDZlP+bDPR1xXpcOAx2jnfOP9A3zcg4/mzufgU8/w3hEgMB4yrv8AHmuReSpl8u HZzyzNRJ92oIKBbAOlJSzcT4RPnvKCA3uvKS 1 row selected. SQL> SQL> BEGIN 2 wraptest; -- invoke procedure 3 DBMS_OUTPUT.PUT_LINE('fibonacci(5) = ' || fibonacci(5)); 4 END; 5 / Emp Id: 100 Emp Id: 101 Emp Id: 102 Emp Id: 103 Emp Id: 104 Emp Id: 105 Emp Id: 106 Emp Id: 107 Emp Id: 108 Emp Id: 109 fibonacci(5) = 3 PL/SQL procedure successfully completed. SQL>
DBMS_DDL
パッケージには、WRAP
ファンクションおよびCREATE_WRAPPED
プロシージャが含まれていて、各ファンクションおよびプロシージャは、動的に生成された単一のラップ可能PL/SQLユニットのPL/SQLソース・テキストをラップします。また、DBMS_DDL
パッケージには、WRAPまたはCREATE_WRAPPED
への入力が有効なラップ可能PL/SQLユニットでない場合に発生する、例外MALFORMED_WRAP_INPUT
(ORA-24230)も含まれます。(ラップ可能PL/SQLユニットのリストは、「PL/SQLのソース・テキストのラップ」の概要を参照してください。)
各WRAP
ファンクションは、ラップ可能PL/SQLユニットを作成する単一のCREATE
文を入力として取得し、PL/SQLソース・テキストがラップされた同等のCREATE
文を戻します。WRAP
ファンクションの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。
注意:
DBMS_DDL
.WRAP
によって戻される文を、データ型がVARCHAR2A
の仮パラメータstatement
を含むDBMS_SQL
.PARSE
プロシージャに渡す場合、DBMS_SQL
.PARSE
のlfflg
パラメータをFALSE
に設定する必要があります。設定しないと、DBMS_SQL
.PARSE
によって、ラップされたPL/SQLユニットに行が追加され、ユニットが破損します。(DBMS_SQL
.PARSE
の構文は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。)
各CREATE_WRAPPED
プロシージャは、その対応するWRAP
ファンクションと同じ処理を行って、戻されたCREATE
文を実行し、指定されたPL/SQLユニットを作成します。CREATE_WRAPPED
プロシージャの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。
ヒント:
DBMS_DDL
サブプログラムの起動時には、パッケージの完全修飾名SYS.DBMS_DDL
を使用し、他のユーザーがDBMS_DDL
という名前のローカル・パッケージを作成していたり、パブリック・シノニムDBMS_DDL
を定義している場合に発生する名前の競合を回避します。
注意:
WRAP
ファンクションまたはCREATE_WRAPPED
プロシージャに入力されるCREATE
文は、そのサブプログラムを起動したユーザーの権限で実行されます。
例A-4では、EXECUTE
IMMEDIATE
文を使用してパッケージ仕様部を、およびCREATE_WRAPPED
プロシージャを使用してラップされたパッケージ本体を動的に作成します。
例A-5では、例A-4で作成したパッケージemp_actions
のテキストを選択し、プロシージャemp_actions.raise_salary
を起動します。パッケージ仕様部がラップされている場合、プロシージャを起動するために必要な情報は、パッケージ本体のPL/SQLソース・テキストのように判読不可能になります。
例A-4 CREATE_WRAPPEDプロシージャによるラップされたパッケージ本体の作成
DECLARE
package_text VARCHAR2(32767); -- text for creating package spec and body
FUNCTION generate_spec (pkgname VARCHAR2) RETURN VARCHAR2 AS
BEGIN
RETURN 'CREATE PACKAGE ' || pkgname || ' AUTHID CURRENT_USER 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
EXECUTE IMMEDIATE package_text; -- Create package spec
package_text := generate_body('emp_actions'); -- Generate package body
SYS.DBMS_DDL.CREATE_WRAPPED(package_text); -- Create wrapped package body
END;
/
例A-5 ラップされた本体を含むパッケージの表示およびパッケージ・プロシージャの起動
パッケージのテキストの選択:
SELECT text FROM USER_SOURCE WHERE name = 'EMP_ACTIONS';
結果:
TEXT ------------------------------------------------------------------------ PACKAGE emp_actions AUTHID CURRENT_USER AS PROCEDURE raise_salary (emp_id NUMBER, amount NUMBER); PROCEDURE fire_employee (emp_id NUMBER); END emp_actions; PACKAGE BODY emp_actions wrapped a000000 1f abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd b 180 113 1fOVodewm7j9dBOmBsiEQz0BKCgwg/BKoZ4VZy/pTBIYo8Uj1sjpbEz08Ck3HMjYq/Mf0XZn u9D0Kd+i89g9ZO61I6vZYjw2AuBidnLESyR63LHZpFD/7lyDTfF1eDY5vmNwLTXrFaxGy243 0lHKAzmOlwwfBWylkZZNi2UnpmSIe6z/BU2nhbwfpqd224p69FwYVXmFX2H5IMsdZ2/vWsK9 cDMCD1KEqOnPpbU2yXdpW3GIbGD8JFIbKAfpJLkoLfVxoRPXQfj0h1k=
raised_salary
の起動およびその影響の表示:
DECLARE
s employees.salary%TYPE;
BEGIN
SELECT salary INTO s FROM employees WHERE employee_id=130;
DBMS_OUTPUT.PUT_LINE('Old salary: ' || s);
emp_actions.raise_salary(130, 100);
SELECT salary INTO s FROM employees WHERE employee_id=130;
DBMS_OUTPUT.PUT_LINE('New salary: ' || s);
END;
/
結果:
Old salary: 3557.4 New salary: 3657.4 PL/SQL procedure successfully completed.