ヘッダーをスキップ
Oracle Database PL/SQL言語リファレンス
11g リリース1(11.1)
E05670-03
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

A PL/SQLのソース・コードのラップ

この付録では、ラップの概要、PL/SQLコードをラップする理由およびその方法について説明します。

ここでのトピック:

ラップの概要

ラップとは、PL/SQLソース・コードを隠す処理のことです。ラップは、競合他社やソース・コードを間違って使用する可能性のあるユーザーからソース・コードを保護する際に役立ちます。

PL/SQLソース・コードをラップするには、wrapユーティリティまたはDBMS_DDLサブプログラムのいずれかを使用します。wrapユーティリティによって、SQL*Plusスクリプトなどの単一のソース・ファイルがラップされます。 DBMS_DDLサブプログラムでは、単一のCREATE PROCEDURE文などの動的に生成された単一のPL/SQLユニットがラップされます。

ラップされたソース・ファイルは、SQL*Plus、インポート・ユーティリティおよびエクスポート・ユーティリティによって移動、バックアップおよび処理することはできますが、静的データ・ディクショナリ・ビュー*_SOURCEから参照されません。


注意:

すでにラップされたファイルをラップしてもそのファイルに影響はありません。

ラップのガイドライン

ラップの制限

wrapユーティリティを使用したPL/SQLコードのラップ

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
wrap iname=/mydir/myfile.sql

次のように、異なるファイル拡張子を指定することもできます。

wrap iname=/mydir/myfile.src

output_fileは、作成するファイル(ラップされたファイル)の名前です。これがデフォルトで入力ファイルの名前となり、拡張子はデフォルトで.plbとなります。たとえば、次のコマンドは同じ意味を持ちます。

wrap iname=/mydir/myfile
wrap iname=/mydir/myfile.sql oname=/mydir/myfile.plb

次に示すように、onameオプションを使用して、異なるファイル名と拡張子を指定できます。

wrap iname=/mydir/myfile oname=/yourdir/yourfile.out

注意:

input_fileがすでにラップされている場合、output_fileinput_fileと同じです。

ここでのトピック:

PL/SQLのwrapユーティリティの入力ファイルと出力ファイル

入力ファイルでは、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ユーティリティの実行

たとえば、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();

PL/SQLのwrapユーティリティの制限

  • ラップされるPL/SQLコードにSQL*PlusのDEFINE表記法を使用して置換変数を含めることはできません。

    ラップされたソース・コードは、SQL*Plusではなく、PL/SQLコンパイラによって解析されます。

  • wrapユーティリティによって、ラップされたファイルからほとんどのコメントが削除されます。

    「PL/SQLのwrapユーティリティの入力ファイルと出力ファイル」を参照してください。

DBMS_DDLサブプログラムを使用したPL/SQLコードのラップ

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)も含まれます。


注意:

すでにラップされているPL/SQLユニットをラップしても、そのユニットに影響はありません。

ここでのトピック:


参照:

DBMS_DDLパッケージの詳細は『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

DBMS_DDL.CREATE_WRAPPEDプロシージャの使用

例A-1では、CREATE_WRAPPEDを使用して、データベースにパッケージ仕様部およびパッケージ本体を動的に作成し、ラップしています。

例A-1 DBMS_DDL.CREATE_WRAPPEDプロシージャを使用したパッケージのラップ

DECLARE
  package_text VARCHAR2(32767); -- text for creating package spec & body

  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
  -- Generate package spec
  package_text := generate_spec('emp_actions')

  -- Create wrapped package spec
  DBMS_DDL.CREATE_WRAPPED(package_text);

  -- Generate package body
  package_text := generate_body('emp_actions');

  -- Create wrapped package body
  DBMS_DDL.CREATE_WRAPPED(package_text);
END;
/

-- Invoke procedure from wrapped package
CALL emp_actions.raise_salary(120, 100);

静的データ・ディクショナリ・ビュー*_SOURCEを表示しても、ソースがラップされている(表示されない)ため、他のユーザーはコードの詳細を参照できません。次に例を示します。

SELECT text FROM USER_SOURCE WHERE name = 'EMP_ACTIONS';

出力結果は、次のようになります。

TEXT
--------------------------------------------------------------------
PACKAGE emp_actions WRAPPED
a000000
1f
abcd
...

DBMS_DDL.WRAPファンクションの制限

DBMS_DDL.WRAPの出力でDBMS_SQL.PARSEを起動する場合(32767バイトを超えるテキストに対する文の仮パラメータのデータ型がVARCHAR2AまたはVARCHAR2Sであるオーバーロードを使用するとき)は、LFFLGパラメータにFALSEを設定する必要があります。設定しないと、DBMS_SQL.PARSEによって、ラップされたユニットに改行が追加されるため、ユニットが破損します。