ヘッダーをスキップ
Oracle® Database PL/SQL言語リファレンス
11gリリース2 (11.2)
B56260-09
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

A PL/SQLのソース・テキストのラップ

次の任意のストアド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サブプログラムでは、トークン化エラー(文字列の欠落など)は検出されますが、構文エラーやセマンティック・エラー(表やビューが存在しないなど)は検出されません。

11.2 PL/SQLコンパイラは、デフォルトで、9.2 PL/SQLコンパイラでコンパイルされているラップされたパッケージを使用できます。11.2 PL/SQLコンパイラが9.2 PL/SQLコンパイラでコンパイルされているラップされたパッケージを使用できないようにするには、PL/SQLコンパイル・パラメータPERMIT_92_WRAP_FORMATFALSEに設定します。PERMIT_92_WRAP_FORMATの詳細は、『Oracle Databaseリファレンス』を参照してください。PL/SQLのコンパイル・パラメータの詳細は、「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行トリガーを記述します。

PL/SQLソース・テキストのラップのガイドライン

  • パッケージまたは型の仕様部ではなく、本体のみをラップします。

    仕様部をラップしないことで、他の開発者は、パッケージまたは型を使用するために必要な情報を見ることができます(例A-5を参照)。本体はラップされているため、パッケージまたは型の実装は、他の開発者から隠されます。

  • ファイルの編集が完了した後にのみ、ファイルをラップします。

    ラップされたファイルは、編集できません。ラップされたファイルの変更が必要な場合、ラップされていない元のファイルを編集し、再度ラップする必要があります。

  • ラップされたファイルを配布する前に、テキスト・エディタで表示して重要な部分がすべてラップされていることを確認します。

PL/SQLラッパー・ユーティリティによるPL/SQLソース・テキストのラップ


注意:

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言語リファレンス』の構文図にあるCREATEplsql_sourceの間)

  • /*および*/で区切られたコメント


注意:

input_fileがラップされたファイルの場合、input_fileoutput_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-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 DEFINER 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 DEFINER
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ラッパー・ユーティリティを使用してwraptest2.sqlをラップし、そのラップされたファイルwraptest2.plbを表示します。ラップされたファイルでは、ユーティリティによって--で始まるコメントが削除され、プロシージャwraptestおよびファンクションfibonacciのPL/SQLソース・テキストがラップされた(判読不可能にされた)ことがわかりますが、SELECT文や、/*および*/で区切られたコメントは変更されていません。

例A-2 PL/SQLラッパー・ユーティリティによるファイルのラップ

オペレーティング・システム・プロンプトが>であると仮定。ファイルwraptest.sqlのラップ:

> wrap iname=wraptest2.sql

結果:

PL/SQL Wrapper: Release 11.2.0.1.0- Production on Wed Sep 15 08:10:15 2010
 
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
b2
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
121 134
Pf3/wD+9ncRZhp3XxTMUO3yIRvswg+nQ7UhqfHRG2vg+SD7x9XzsDUFWbdwCJVEOLKBBRuH6
VMoRHfX6apzfyMkvWhzQLCYvAcq6Zu7++E7PrXNxUJzk/FZW8P9eRgyyyMFnDj53aP1cDje9
ZdGr2VmJHIw0ZNHBYhDdR+du5U5Yy47a6dJHXFW9eNyxBHtXZDuiWYTUtlnueHQV9iYDwE+r
jFn+eZm4jgDcTLTEzfmIVtPDRNhYCY3xhPo7vJeS8M1AvP+4xh9+uO35XsRIsRl1PTFVrGwg
6iuxETwA5Pu2mwx3
 
/
CREATE OR REPLACE FUNCTION fibonacci wrapped 
a000000
b2
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
8
14a fb
e1Yq3QQJoEoNKIeJlbgLoLdSgogwgxDcf8vWfHSKbuowFOXFKoj9MqYGqWyRxeeCUVqNVIO1
ICqJa3yPr6e7z8GZpMH3J0Cx0uQ0B1JuysymdNDlzfTvb7QWsrLU4jGs3h8Mm49/L9nyO4Xh
Ae06nawFpOJIAYpBf9wBVC+ZrjU/nuEtokBqCce6HWIoF6rYgz0V0W/47x5KpOnQ2i7X3kFe
FR8K7jT7X58k8xK9uYlZv5LhV71a7A==
 
/

例A-3では、ラップされたファイルwraptest.plbをSQL*Plusで実行し、プロシージャwraptestおよびファンクションfibonacciを作成します。各サブプログラムのテキスト(ラップされているため判読不可能)を選択し、その後、サブプログラムを起動します。

例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  b2
  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  121 134
 21  Pf3/wD+9ncRZhp3XxTMUO3yIRvswg+nQ7UhqfHRG2vg+SD7x9XzsDUFWbdwCJVEOLKBBRuH6
 22  VMoRHfX6apzfyMkvWhzQLCYvAcq6Zu7++E7PrXNxUJzk/FZW8P9eRgyyyMFnDj53aP1cDje9
 23  ZdGr2VmJHIw0ZNHBYhDdR+du5U5Yy47a6dJHXFW9eNyxBHtXZDuiWYTUtlnueHQV9iYDwE+r
 24  jFn+eZm4jgDcTLTEzfmIVtPDRNhYCY3xhPo7vJeS8M1AvP+4xh9+uO35XsRIsRl1PTFVrGwg
 25  6iuxETwA5Pu2mwx3
 26  
 27  /
 
Procedure created.
 
SQL> CREATE OR REPLACE FUNCTION fibonacci wrapped
  2  a000000
  3  b2
  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  14a fb
 21  e1Yq3QQJoEoNKIeJlbgLoLdSgogwgxDcf8vWfHSKbuowFOXFKoj9MqYGqWyRxeeCUVqNVIO1
 22  ICqJa3yPr6e7z8GZpMH3J0Cx0uQ0B1JuysymdNDlzfTvb7QWsrLU4jGs3h8Mm49/L9nyO4Xh
 23  Ae06nawFpOJIAYpBf9wBVC+ZrjU/nuEtokBqCce6HWIoF6rYgz0V0W/47x5KpOnQ2i7X3kFe
 24  FR8K7jT7X58k8xK9uYlZv5LhV71a7A==
 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
b2
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
121 134
Pf3/wD+9ncRZhp3XxTMUO3yIRvswg+nQ7UhqfHRG2vg+SD7x9XzsDUFWbdwCJVEOLKBBRuH6
VMoRHfX6apzfyMkvWhzQLCYvAcq6Zu7++E7PrXNxUJzk/FZW8P9eRgyyyMFnDj53aP1cDje9
ZdGr2VmJHIw0ZNHBYhDdR+du5U5Yy47a6dJHXFW9eNyxBHtXZDuiWYTUtlnueHQV9iYDwE+r
jFn+eZm4jgDcTLTEzfmIVtPDRNhYCY3xhPo7vJeS8M1AvP+4xh9+uO35XsRIsRl1PTFVrGwg
6iuxETwA5Pu2mwx3
 
 
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
b2
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
8
14a fb
e1Yq3QQJoEoNKIeJlbgLoLdSgogwgxDcf8vWfHSKbuowFOXFKoj9MqYGqWyRxeeCUVqNVIO1
ICqJa3yPr6e7z8GZpMH3J0Cx0uQ0B1JuysymdNDlzfTvb7QWsrLU4jGs3h8Mm49/L9nyO4Xh
Ae06nawFpOJIAYpBf9wBVC+ZrjU/nuEtokBqCce6HWIoF6rYgz0V0W/47x5KpOnQ2i7X3kFe
FR8K7jT7X58k8xK9uYlZv5LhV71a7A==
 
 
1 row selected.
 
SQL> 
SQL> BEGIN
  2    wraptest;  -- invoke procedure
  3    DBMS_OUTPUT.PUT_LINE('fibonacci(5) = ' || fibonacci(5));
  4  END;
  5  /
Emp Id: 198
Emp Id: 199
Emp Id: 200
Emp Id: 201
Emp Id: 202
Emp Id: 203
Emp Id: 204
Emp Id: 205
Emp Id: 206
Emp Id: 100
fibonacci(5) = 3
 
PL/SQL procedure successfully completed.
 
SQL> 

DBMS_DDLサブプログラムによるPL/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.PARSElfflgパラメータを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-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 DEFINER 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では、例A-4で作成したパッケージemp_actionsのテキストを選択し、プロシージャemp_actions.raise_salaryを起動します。パッケージ仕様部がラップされている場合、プロシージャを起動するために必要な情報は、パッケージ本体のPL/SQLソース・テキストのように判読不可能になります。

例A-5 ラップされた本体を含むパッケージの表示およびパッケージ・プロシージャの起動

パッケージのテキストの選択:

SELECT text FROM USER_SOURCE WHERE name = 'EMP_ACTIONS';

結果:

TEXT
------------------------------------------------------------------------
 
PACKAGE emp_actions AUTHID DEFINER AS
      PROCEDURE raise_salary (emp_id NUMBER, amount NUMBER);
      PROCEDURE fire_employee (emp_id NUMBER);
      END emp_actions;
PACKAGE BODY emp_actions wrapped
a000000
369
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: 2800
New salary: 2900
 
PL/SQL procedure successfully completed.