Sunteți pe pagina 1din 5

Dynamically wrap PLSQL code Oracle Maniacs' Notes

http://oraclemaniac.com/2012/06/12/dynamically-wrap-plsql-code/

Oracle Maniacs' Notes


Interesting, out-of-the-box or just plain information PL/SQL

Dynamically wrap PLSQL code


Posted by Abhit Ray June 12, 2012 Leave a Comment Filed Under .plb, .pls, all_source, create_wrapped, DBMS_DDL, DBMS_SQL, iname, oname, varchar2a As a developer we might not like to keep the source code available for all database users to view and modify. The reason could be to keep copyright of source code or to stop unauthorized changes made within the code. Oracle has provided the WRAP utility to encrypt source code for this purpose. The WRAP utility can be invoked on the operating system, like Windows, command line as it comes with the Oracle client. It can also be invoked within the database using DBMS_DDL package. I have illustrated below how both methods can be used. Command line Wrap utility Normally PL/SQL code is wrapped using the wrap utility given by Oracle. This is a command line tool and can be used as shown below.
1 wrap iname=input_file [oname=output_file]

Create a le named, get_date_string.sql with the following code,


1 2 3 4 5 CREATE OR REPLACE FUNCTION get_date_string RETURN VARCHAR2 AS BEGIN RETURN TO_CHAR(SYSDATE, 'DDMONYYYY'); END get_date_string; /

On the windows command line go to the directory where you saved the le, get_date_string.sql. Execute the following command to wrap the code,
1 Wrap iname=get_date_string.sql

The code is now wrapped into a new le with .plb extension. Now compile this le in the database. If you execute the function in SQL you will get the output If you describe the function you will only get the function signature. This is true for wrapped as well as unwrapped code. Let us check the code in the database
1 select * from all_source where name = 'GET_DATE_STRING'

1 de 5

12/09/2012 11:33 a.m.

Dynamically wrap PLSQL code Oracle Maniacs' Notes

http://oraclemaniac.com/2012/06/12/dynamically-wrap-plsql-code/

The code cannot be viewed any more. Using PL/SQL to wrap source code We can directly embed PL/SQL code into another PL/SQL code to wrap and compile it. The following code is an example.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 END; / Display each line of the wrapped code FOR i IN 1 .. sql_wrap_t.COUNT LOOP DBMS_OUTPUT.put_line (sql_wrap_t (i)); END LOOP; Now compile and wrap the code sql_wrap_t := SYS.DBMS_DDL.wrap (DDL => sql_text_t, lb ub ); => 1, => sql_text_t.COUNT DECLARE sql_text_t sql_wrap_t DBMS_SQL.varchar2a; DBMS_SQL.varchar2a;

BEGIN Store the PL/SQL code in the array or PL/SQL table Each line of code will go into a new row sql_text_t (1) := 'CREATE OR REPLACE FUNCTION get_date_string RETURN VARCHAR2 AS '; sql_text_t (2) := 'BEGIN '; sql_text_t (3) := 'RETURN TO_CHAR(SYSDATE, ''DDMONYYYY''); '; sql_text_t (4) := 'END get_date_string;';

We have embedded PL/SQL code for a function named get_date_string in the main PL/SQL block that will compile this function in to the database. Aer executing the code the output is,
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 CREATE OR REPLACE FUNCTION get_date_string wrapped a000000 230 abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd 8 6f aa mV4eMSJ8EqqgErJT91l6UZ0pdDUwgyr6LZ5GfHSmUPiJfkEObQpeDb6D7glajI+ONulxdqC1 0HvOPP4eJpQs5zxsKXpj6XL1fvieXyWCr3BTzXTqcGYhfXrtqDVPztR/o+9UZ8l5OijDSsRW ZPv6rISzFyqeEsCBweFUFyxd

2 de 5

12/09/2012 11:33 a.m.

Dynamically wrap PLSQL code Oracle Maniacs' Notes

http://oraclemaniac.com/2012/06/12/dynamically-wrap-plsql-code/

Now this function is available in the database and is wrapped. We shall call this function to see how it works,
1 select get_date_string from dual

The function is fully functional but its code cannot be queried from the database. Since this piece of code was very small embedding it into a PL/SQL block was very easy. What happens if the PL/SQL code is several thousand lines long? In that case it is beer to compile the code into the database rst and then execute a PL/SQL code to wrap and compile it. The following code compiles and wraps FUNCTIONS, PROCEDURES and PACKAGE BODIES which have already been compiled into the database. Code to wrap PL/SQL FUNCTION/PROCEDURE/PACKAGE BODIES
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 IF (v_object_type = 'PROCEDURE' OR v_object_type = 'FUNCTION') THEN Open the cursor by passing the name of the package OPEN c_procedure (v_object_name); END; Pick up the code only from APPS schema CURSOR c_procedure (v_procedure VARCHAR2) IS SELECT text FROM all_source WHERE NAME = v_procedure AND TYPE = 'PROCEDURE' AND owner = 'APPS'; BEGIN BEGIN Check the type of code SELECT object_type INTO v_object_type FROM all_objects WHERE object_name = v_object_name AND status = 'VALID'; EXCEPTION WHEN TOO_MANY_ROWS THEN The select statement will fail for a package as there will be 2 rows. 1 for package spec and 1 for package body v_object_type := 'PACKAGE BODY'; Pick up the code only from APPS schema CURSOR c_package_body (v_package_name VARCHAR2) IS SELECT text FROM all_source WHERE NAME = v_package_name AND TYPE = 'PACKAGE BODY' AND owner = 'APPS'; SET SERVEROUTPUT ON SIZE UNLIMITED DECLARE sql_text_t v_object_type v_object_name

DBMS_SQL.varchar2a; VARCHAR2 (40); VARCHAR2 (60) := 'XXEYAP_INVOICES_INT_PKG';

3 de 5

12/09/2012 11:33 a.m.

Dynamically wrap PLSQL code Oracle Maniacs' Notes

http://oraclemaniac.com/2012/06/12/dynamically-wrap-plsql-code/

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 END; / Call the Oracle package to reompile the code and encrypt it into the database DBMS_DDL.create_wrapped (DDL => sql_text_t, => 1, => sql_text_t.COUNT lb ub ); Since the code stored in the database does not contain the DDL text, CREATE OR REPLACE, we are adding this part in the beginning of the first line as the package body will be recompiled sql_text_t (1) := 'CREATE OR REPLACE ' || sql_text_t (1); CLOSE c_package_body; END IF; Get each line of code into each array row, i.e. PL/SQL table FETCH c_package_body BULK COLLECT INTO sql_text_t; CLOSE c_procedure; ELSIF v_object_type = 'PACKAGE BODY' THEN Open the cursor by passing the name of the package OPEN c_package_body (v_object_name); Get each line of code into each array row, i.e. PL/SQL table FETCH c_procedure BULK COLLECT INTO sql_text_t;

Step 1: Query for the package body in the database


1 2 3 SELECT * FROM all_source WHERE NAME = 'XXEYAP_INVOICES_INT_PKG' AND TYPE = 'PACKAGE BODY'

Output Step 2: Execute the code to wrap the package body The code is executed through any means, PL/SQL, forms, reports, etc. Step 3: Query for the package body again If you now check for the package in TOAD The package spec will be unwrapped The package body will be wrapped, Now the source code is encrypted but the package can be utilized fully with no loss in performance or functionality. You will nd several Oracle packages wrapped in the same way. The Oracle package that we have utilized in this example, DBMS_DDL, is a good example. We can

4 de 5

12/09/2012 11:33 a.m.

Dynamically wrap PLSQL code Oracle Maniacs' Notes

http://oraclemaniac.com/2012/06/12/dynamically-wrap-plsql-code/

read the package spec but not the body. Have a nice day. Related articles PL/SQL code to set prole option values (oraclemaniac.com) How to start a workow using PL/SQL (oraclemaniac.com) PL/SQL program to move request sets between request groups (oraclemaniac.com)

About Abhijit Ray


I love sleeping, watching Hollywood blockbusters, my Wii, road trips and watching my 4 year old son grow up. In between I try to squeeze in some time to go to work. View all posts by Abhit Ray

Discussion

No comments yet.

Oracle Maniacs Notes Blog at WordPress.com. Theme: The Morning Aer by WooThemes.

5 de 5

12/09/2012 11:33 a.m.

S-ar putea să vă placă și