You are on page 1of 8

A Wrapping PL/SQL Source Code

This appendix explains what wrapping is, why you wrap PL/SQL code, and how to do it.
Topics:

Overview of Wrapping
Guidelines for Wrapping
Limitations of Wrapping
Wrapping PL/SQL Code with wrap Utility
Wrapping PL/QL Code with DBMS_DDL Subprograms

Overview of Wrapping
Wrapping is the process of hiding PL/SQL source code. Wrapping helps to
protect your source code from business competitors and others who might
misuse it.
You can wrap PL/SQL source code with either the wrap utility
or DBMS_DDL subprograms. The wrap utility wraps a single source file, such as a
SQL*Plus script. The DBMS_DDL subprograms wrap a single dynamically
generated PL/SQL unit, such as a single CREATE PROCEDUREstatement.
Wrapped source files can be moved, backed up, and processed by SQL*Plus and
the Import and Export utilities, but they are not visible through the static data
dictionary views *_SOURCE.

Note:
Wrapping a file that is already wrapped has no effect on the file.

Guidelines for Wrapping

Wrap only the body of a package or object type, not the specification.
This allows other developers to see the information they must use the
package or type, but prevents them from seeing its implementation.

Wrap code only after you have finished editing it.


You cannot edit PL/SQL source code inside wrapped files. Either wrap
your code after it is ready to ship to users or include the wrapping
operation as part of your build environment.
To change wrapped PL/SQL code, edit the original source file and then
wrap it again.

Before distributing a wrapped file, view it in a text editor to be sure that


all important parts are wrapped.

Limitations of Wrapping

Wrapping is not a secure method for hiding passwords or table names.


Wrapping a PL/SQL unit prevents most users from examining the source
code, but might not stop all of them.

Wrapping does not hide the source code for triggers.


To hide the workings of a trigger, write a one-line trigger that invokes a
wrapped subprogram.

Wrapping does not detect syntax or semantic errors.


Wrapping detects only tokenization errors (for example, runaway strings),
not syntax or semantic errors (for example, nonexistent tables or views).
Syntax or semantic errors are detected during PL/SQL compilation or
when executing the output file in SQL*Plus.

Wrapped PL/SQL units are not downward-compatible.


Wrapped PL/SQL units are upward-compatible between Oracle Database
releases, but are not downward-compatible. For example, you can load
files processed by the V8.1.5 wrap utility into a V8.1.6 Oracle Database,
but you cannot load files processed by the V8.1.6 wrap utility into a
V8.1.5 Oracle Database.

See Also:

Limitations of the wrap Utility


Limitation of the DBMS_DDL.WRAP Function

Wrapping PL/SQL Code with wrap Utility


The wrap utility processes an input SQL file and wraps only the PL/SQL units in
the file, such as a package specification, package body, function, procedure,
type specification, or type body. It does not wrap PL/SQL content in anonymous
blocks or triggers or non-PL/SQL code.
To run the wrap utility, enter the wrap command at your operating system
prompt using the following syntax (with no spaces around the equal signs):
wrap iname=input_file [ oname=output_file ]
input_file is the name of a file containing SQL statements, that you typically
run using SQL*Plus. If you omit the file extension, an extension of .sql is

assumed. For example, the following commands are equivalent:


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

You can also specify a different file extension:


wrap iname=/mydir/myfile.src
output_file is the name of the wrapped file that is created. The defaults to that
of the input file and its extension default is .plb. For example, the following

commands are equivalent:

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

You can use the option oname to specify a different file name and extension:
wrap iname=/mydir/myfile oname=/yourdir/yourfile.out

Note:
If input_file is already wrapped, output_file will be identical to input_file .
Topics:

Input and Output Files for the PL/SQL wrap Utility


Running the wrap Utility
Limitations of the wrap Utility

Input and Output Files for the PL/SQL wrap Utility


The input file can contain any combination of SQL statements. Most statements
are passed through unchanged. CREATE statements that define subprograms,
packages, or object types are wrapped; their bodies are replaced by a
scrambled form that the PL/SQL compiler understands.
The following CREATE statements are wrapped:
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

The CREATE [OR REPLACE] TRIGGER statement, and [DECLARE] BEGINEND anonymous blocks, are not wrapped. All other SQL statements are passed
unchanged to the output file.

All comment lines in the unit being wrapped are deleted, except for those in
a CREATE OR REPLACE header and C-style comments (delimited by /* */).
The output file is a text file, which you can run as a script in SQL*Plus to set up
your PL/SQL subprograms and packages. Run a wrapped file as follows:
SQL> @wrapped_file_name.plb;

Running the wrap Utility


For example, assume that the wrap_test.sql file contains the following:
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;
/

To wrap the file, run the following from the operating system prompt:
wrap iname=wrap_test.sql

The output of the wrap utility is similar to the following:


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

If you view the contents of the wrap_test.plb text file, the first line
is CREATE PROCEDURE wraptest wrapped and the rest of the file contents is
hidden.
You can run wrap_test.plb in SQL*Plus to execute the SQL statements in the
file:
SQL> @wrap_test.plb

After the wrap_test.plb is run, you can execute the procedure that was
created:
SQL> CALL wraptest();

Limitations of the wrap Utility

The PL/SQL code to be wrapped cannot include substitution variables


using the SQL*Plus DEFINE notation.
Wrapped source code is parsed by the PL/SQL compiler, not by SQL*Plus.

The wrap utility removes most comments from wrapped files.


See Input and Output Files for the PL/SQL wrap Utility.

Wrapping PL/QL Code with DBMS_DDL


Subprograms
The DBMS_DDL package contains procedures for wrapping a single PL/SQL unit,
such as a package specification, package body, function, procedure, type
specification, or type body. These overloaded subprograms provide a
mechanism for wrapping dynamically generated PL/SQL units that are created
in a database.
The DBMS_DDL package contains the WRAP functions and
the CREATE_WRAPPED procedures. The CREATE_WRAPPED both wraps the text and
creates the PL/SQL unit. When invoking the wrap procedures, use the fully
qualified package name, SYS.DBMS_DDL, to avoid any naming conflicts and the
possibility that someone might create a local package called DBMS_DDL or define
the DBMS_DDL public synonym. The inputCREATE OR REPLACE statement executes
with the privileges of the user who
invokes DBMS_DDL.WRAP or DBMS_DDL.CREATE_WRAPPED.
The DBMS_DDL package also provides the MALFORMED_WRAP_INPUT exception (ORA24230) which is raised if the input to the wrap procedures is not a valid PL/SQL
unit.

Note:
Wrapping a PL/SQL unit that is already wrapped has no effect on the unit.
Topics:

Using DBMS_DDL.CREATE_WRAPPED Procedure


Limitation of the DBMS_DDL.WRAP Function

See Also:
Oracle Database PL/SQL Packages and Types Reference for information about
the DBMS_DDL package

Using DBMS_DDL.CREATE_WRAPPED Procedure


In Example A-1 CREATE_WRAPPED is used to dynamically create and wrap a
package specification and a package body in a database.
Example A-1 Using DBMS_DDL.CREATE_WRAPPED Procedure to Wrap a
Package
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);

When you check the static data dictionary views *_SOURCE, the source is
wrapped, or hidden, so that others cannot view the code details. For example:
SELECT text FROM USER_SOURCE WHERE name = 'EMP_ACTIONS';

The resulting output is similar to the following:


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

...

Limitation of the DBMS_DDL.WRAP Function


If you invoke DBMS_SQL.PARSE (when using an overload where the statement
formal has data type VARCHAR2A or VARCHAR2S for text which exceeds 32767
bytes) on the output of DBMS_DDL.WRAP, then you must set the LFFLG parameter
to FALSE. Otherwise DBMS_SQL.PARSEadds newlines to the wrapped unit which
corrupts the unit.

You might also like