Upload
julioyc
View
24
Download
2
Embed Size (px)
Citation preview
Oracle Maniacs' Notes
Interesting, out-of-the-box or just plain informationPL/SQL
Dynamically wrap PLSQL code
Posted by Abhijit Ray ⋅ June 12, 2012 ⋅ Leave a CommentFiled Under .plb, .pls, all_source, create_wrapped, DBMS_DDL, DBMS_SQL, iname, oname,varchar2aAs a developer we might not like to keep the source code available for all database users to viewand modify. The reason could be to keep copyright of source code or to stop unauthorizedchanges made within the code. Oracle has provided the WRAP utility to encrypt source code forthis purpose. The WRAP utility can be invoked on the operating system, like Windows, commandline as it comes with the Oracle client. It can also be invoked within the database usingDBMS_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 linetool and can be used as shown below.
Create a file named, get_date_string.sql with the following code,
On the windows command line go to the directory where you saved the file, get_date_string.sql.Execute the following command to wrap the code,
The code is now wrapped into a new file with .plb extension. Now compile this file in thedatabase.
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 aswell as unwrapped code.
Let us check the code in the database
1 wrap iname=input_file [oname=output_file]
1 CREATE OR REPLACE FUNCTION get_date_string RETURN VARCHAR2 AS
2 BEGIN
3 RETURN TO_CHAR(SYSDATE, 'DD‐MON‐YYYY');
4 END get_date_string;
5 /
1 Wrap iname=get_date_string.sql
1 select * from all_source where name = 'GET_DATE_STRING'
Dynamically wrap PLSQL code « Oracle Maniacs' Notes http://oraclemaniac.com/2012/06/12/dynamically-wrap-plsql-code/
1 de 5 12/09/2012 11:33 a.m.
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. Thefollowing code is an example.
We have embedded PL/SQL code for a function named get_date_string in the main PL/SQLblock that will compile this function in to the database.
A6er executing the code the output is,
01 DECLARE
02 sql_text_t DBMS_SQL.varchar2a;
03 sql_wrap_t DBMS_SQL.varchar2a;
04 BEGIN
05 ‐‐ Store the PL/SQL code in the array or PL/SQL table
06 ‐‐ Each line of code will go into a new row
07 sql_text_t (1) := 'CREATE OR REPLACE FUNCTION get_date_string RETURN VARCHAR2 AS ';
08 sql_text_t (2) := 'BEGIN ';
09 sql_text_t (3) := 'RETURN TO_CHAR(SYSDATE, ''DD‐MON‐YYYY''); ';
10 sql_text_t (4) := 'END get_date_string;';
11
12 ‐‐ Now compile and wrap the code
13 sql_wrap_t := SYS.DBMS_DDL.wrap (DDL => sql_text_t,
14 lb => 1,
15 ub => sql_text_t.COUNT
16 );
17
18 ‐‐ Display each line of the wrapped code
19 FOR i IN 1 .. sql_wrap_t.COUNT
20 LOOP
21 DBMS_OUTPUT.put_line (sql_wrap_t (i));
22 END LOOP;
23 END;
24 /
01 CREATE OR REPLACE FUNCTION get_date_string wrapped
02 a000000
03 230
04 abcd
05 abcd
06 abcd
07 abcd
08 abcd
09 abcd
10 abcd
11 abcd
12 abcd
13 abcd
14 abcd
15 abcd
16 abcd
17 abcd
18 abcd
19 8
20 6f aa
21 mV4eMSJ8EqqgErJT91l6UZ0pdDUwgyr6LZ5GfHSmUPiJfkEObQpeDb6D7glajI+ONulxdqC1
22 0HvOPP4eJpQs5zxsKXpj6XL1fvieXyWCr3BTzXTqcGYhfXrtqDVPztR/o+9UZ8l5OijDSsRW
23 ZPv6rISzFyqeEsCBweFUFyxd
Dynamically wrap PLSQL code « Oracle Maniacs' Notes http://oraclemaniac.com/2012/06/12/dynamically-wrap-plsql-code/
2 de 5 12/09/2012 11:33 a.m.
Now this function is available in the database and is wrapped. We shall call this function to seehow it works,
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. Whathappens if the PL/SQL code is several thousand lines long? In that case it is be9er to compile thecode into the database first and then execute a PL/SQL code to wrap and compile it. Thefollowing code compiles and wraps FUNCTIONS, PROCEDURES and PACKAGE BODIESwhich have already been compiled into the database.
Code to wrap PL/SQL FUNCTION/PROCEDURE/PACKAGE BODIES
1 select get_date_string from dual
01 SET SERVEROUTPUT ON SIZE UNLIMITED
02
03 DECLARE
04 sql_text_t DBMS_SQL.varchar2a;
05 v_object_type VARCHAR2 (40);
06 v_object_name VARCHAR2 (60) := 'XXEYAP_INVOICES_INT_PKG';
07
08 ‐‐ Pick up the code only from APPS schema
09 CURSOR c_package_body (v_package_name VARCHAR2)
10 IS
11 SELECT text
12 FROM all_source
13 WHERE NAME = v_package_name AND TYPE = 'PACKAGE BODY' AND owner = 'APPS';
14
15 ‐‐ Pick up the code only from APPS schema
16 CURSOR c_procedure (v_procedure VARCHAR2)
17 IS
18 SELECT text
19 FROM all_source
20 WHERE NAME = v_procedure AND TYPE = 'PROCEDURE' AND owner = 'APPS';
21 BEGIN
22 BEGIN
23 ‐‐ Check the type of code
24 SELECT object_type
25 INTO v_object_type
26 FROM all_objects
27 WHERE object_name = v_object_name AND status = 'VALID';
28 EXCEPTION
29 WHEN TOO_MANY_ROWS
30 THEN
31 ‐‐ The select statement will fail
32 ‐‐ for a package as there will be
33 ‐‐ 2 rows. 1 for package spec and
34 ‐‐ 1 for package body
35 v_object_type := 'PACKAGE BODY';
36 END;
37
38 IF (v_object_type = 'PROCEDURE' OR v_object_type = 'FUNCTION')
39 THEN
40 ‐‐ Open the cursor by passing the name of the package
41 OPEN c_procedure (v_object_name);
Dynamically wrap PLSQL code « Oracle Maniacs' Notes http://oraclemaniac.com/2012/06/12/dynamically-wrap-plsql-code/
3 de 5 12/09/2012 11:33 a.m.
Step 1: Query for the package body in the database
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 inperformance or functionality. You will find several Oracle packages wrapped in the same way. TheOracle package that we have utilized in this example, DBMS_DDL, is a good example. We can
42
43 ‐‐ Get each line of code into each array row, i.e. PL/SQL table
44 FETCH c_procedure
45 BULK COLLECT INTO sql_text_t;
46
47 CLOSE c_procedure;
48 ELSIF v_object_type = 'PACKAGE BODY'
49 THEN
50 ‐‐ Open the cursor by passing the name of the package
51 OPEN c_package_body (v_object_name);
52
53 ‐‐ Get each line of code into each array row, i.e. PL/SQL table
54 FETCH c_package_body
55 BULK COLLECT INTO sql_text_t;
56
57 CLOSE c_package_body;
58 END IF;
59
60 ‐‐ Since the code stored in the database does not
61 ‐‐ contain the DDL text, CREATE OR REPLACE, we are
62 ‐‐ adding this part in the beginning of the first
63 ‐‐ line as the package body will be recompiled
64 sql_text_t (1) := 'CREATE OR REPLACE ' || sql_text_t (1);
65
66 ‐‐ Call the Oracle package to reompile the code
67 ‐‐ and encrypt it into the database
68 DBMS_DDL.create_wrapped (DDL => sql_text_t,
69 lb => 1,
70 ub => sql_text_t.COUNT
71 );
72 END;
73 /
1 SELECT *
2 FROM all_source
3 WHERE NAME = 'XXEYAP_INVOICES_INT_PKG' AND TYPE = 'PACKAGE BODY'
Dynamically wrap PLSQL code « Oracle Maniacs' Notes http://oraclemaniac.com/2012/06/12/dynamically-wrap-plsql-code/
4 de 5 12/09/2012 11:33 a.m.
read the package spec but not the body.
Have a nice day.
Related articles
PL/SQL code to set profile option values (oraclemaniac.com)How to start a workflow 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 oldson grow up. In between I try to squeeze in some time to go to work.View all posts by Abhijit Ray »
Discussion
No comments yet.
Oracle Maniacs ́Notes
Blog at WordPress.com. Theme: The Morning A6er by WooThemes.
Dynamically wrap PLSQL code « Oracle Maniacs' Notes http://oraclemaniac.com/2012/06/12/dynamically-wrap-plsql-code/
5 de 5 12/09/2012 11:33 a.m.