Obfuscating PL/SQL Code
Semantic Designs can construct custom obfuscators for virtually any source language as a part of the corresponding Source Formatter. This page contains PL/SQL sample code, its obfuscated version, and the generated obfuscation map.
PL/SQL Sample Code before Obfuscation
(This is the same formatted code shown on the PL/SQL Formatter example page)
DECLARE
part_no NUMBER(4);
in_stock BOOLEAN;
my_sal REAL(7, 2);
credit_limit CONSTANT NUMBER := 5000.00;
my_title books.title%TYPE;
dept_rec dept%ROWTYPE; -- declare record variableCURSOR c1 IS
emp_rec c1%ROWTYPE; -- declare record variable that represents
-- a row fetched from the emp table
acct_balance NUMBER(11, 2);
acct CONSTANT NUMBER(4) := 3;
debit_amt CONSTANT NUMBER(5, 2) := 500.00;
BEGIN
tax := price * tax_rate;
valid_id := FALSE;
bonus := current_salary * 0.10;
wages := gross_pay(emp_id, st_hrs, ot_hrs) - deductions;
SELECT ename, sal, hiredate, job FROM emp;
SELECT salary * 0.10 INTO bonus FROM employees
WHERE employee_id = emp_id;
SELECT AVG(sal) INTO my_sal FROM emp;
adjust_salary(7788, my_sal); -- assigns a new value to my_sal
FOR someone IN
(SELECT * FROM employees)
LOOP
DBMS_OUTPUT.PUT_LINE('First name = ' || someone.first_name);
DBMS_OUTPUT.PUT_LINE('Last name = ' || someone.last_name);
END LOOP;
my_deptno := dept_rec.deptno;
FETCH c1 INTO emp_rec;
SELECT bal INTO acct_balance FROM accounts
WHERE account_id = acct
FOR UPDATE OF bal;
IF acct_balance >= debit_amt THEN
UPDATE accounts
SET bal = bal - debit_amt
WHERE account_id = acct;
ELSE
INSERT INTO temp
VALUES (acct, acct_balance, 'Insufficient funds');
-- insert account, current balance, and message
END IF;
COMMIT;
-- This CASE statement performs different actions based
-- on a set of conditional tests.
CASE
WHEN shape = 'square' THEN
area := side * side;
WHEN shape = 'circle' THEN
BEGIN
area := pi * (radius * radius);
DBMS_OUTPUT.PUT_LINE('Value is not exact because pi is irrational.');
END;
WHEN shape = 'rectangle' THEN
area := LENGTH * width;
ELSE
BEGIN
DBMS_OUTPUT.PUT_LINE('No formula to calculate area of a' || shape);
RAISE PROGRAM_ERROR;
END;
END CASE;
FOR num IN 1 .. 500 LOOP
INSERT INTO roots
VALUES (num, SQRT(num));
END LOOP;
END;
DECLARE
salary emp.sal%TYPE := 0;
mgr_num emp.mgr%TYPE;
last_name emp.ename%TYPE;
starting_empno emp.empno%TYPE := 7499;
BEGIN
SELECT mgr INTO mgr_num FROM emp
WHERE empno = starting_empno;
WHILE salary <= 2500 LOOP
SELECT sal, mgr, ename INTO salary, mgr_num, last_name FROM emp
WHERE empno = mgr_num;
END LOOP;
INSERT INTO temp
VALUES (NULL, salary, last_name);
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO temp
VALUES (NULL, NULL, 'Not found');
COMMIT;
END;
DECLARE
PROCEDURE award_bonus(emp_id NUMBER) IS
bonus REAL;
comm_missing EXCEPTION;
BEGIN -- executable part starts here
SELECT comm * 0.15 INTO bonus FROM emp
WHERE empno = emp_id;
IF bonus IS NULL THEN
RAISE comm_missing;
ELSE
UPDATE payroll
SET pay = pay + bonus
WHERE empno = emp_id;
END IF;
EXCEPTION -- exception-handling part starts here
WHEN comm_missing THEN
COMMIT;
END award_bonus;
BEGIN
bonus := 1.0;
END;
CREATE PACKAGE emp_actions AS -- package specification
PROCEDURE hire_employee(empno NUMBER,
ename CHAR);
PROCEDURE fire_employee(emp_id NUMBER);
END emp_actions;
CREATE PACKAGE BODY emp_actions AS -- package body
PROCEDURE hire_employee(empno NUMBER,
ename CHAR) IS
BEGIN
INSERT INTO emp
VALUES (empno, ename);
END hire_employee;
PROCEDURE fire_employee(emp_id NUMBER) IS
BEGIN
DELETE FROM emp
WHERE empno = emp_id;
END fire_employee;
END emp_actions;
DECLARE
TYPE Staff IS TABLE OF Employee;
staffer Employee;
FUNCTION new_hires(hiredate DATE)
RETURN Staff IS
BEGIN
NULL;
END;
BEGIN
staffer := new_hires('10-NOV-98') (5);
END;
DECLARE
TYPE TimeRec IS
RECORD (hours SMALLINT,
minutes SMALLINT);
TYPE MeetingTyp IS
RECORD (date_held DATE,
duration TimeRec, -- nested record
location VARCHAR2(20),
purpose VARCHAR2(50));
BEGIN
NULL;
END;
CREATE TYPE Bank_Account AS
OBJECT (acct_number INTEGER(5),
balance REAL,
status VARCHAR2(10),
MEMBER PROCEDURE OPEN (amount IN REAL),
MEMBER PROCEDURE verify_acct(num IN INTEGER),
MEMBER PROCEDURE CLOSE (num IN INTEGER,
amount OUT REAL),
MEMBER PROCEDURE deposit(num IN INTEGER,
amount IN REAL),
MEMBER PROCEDURE withdraw(num IN INTEGER,
amount IN REAL),
MEMBER FUNCTION curr_bal(num IN INTEGER)
RETURN REAL);
DECLARE
comm_missing EXCEPTION; -- declare exception
BEGIN
IF commission IS NULL THEN
RAISE comm_missing; -- raise exception
END IF;
bonus := (salary * 0.10) + (commission * 0.15);
EXCEPTION
WHEN comm_missing THEN
NULL;
END;
DECLARE
n NUMBER;
BEGIN
n := 10E127; -- causes a 'numeric overflow or underflow' error
END;
DECLARE
x BINARY_FLOAT := sqrt(2.0); -- Single-precision floating-point number
y BINARY_DOUBLE := sqrt(2.0); -- Double-precision floating-point number
BEGIN
NULL;
END;
BEGIN
str := 'Hello, world!';
str := 'XYZ Corporation';
str := '10-NOV-91';
str := 'He said "Life is like licking honey from a thorn."';
str := '$1,000,000';
str := q'{I'm a string, you're a string.}'; -- q'!...!' notation lets us use single quotes inside the literal.
string_var := q'{I'm a string, you're a string.}';
-- To use delimiters [, {, <, and (, pair them with ], }, >, and ).
-- Here we pass a string literal representing a SQL statement
-- to a subprogram, without doubling the quotation marks around
-- 'INVALID'.
func_call(q'{select index_name from user_indexes where status = 'INVALID'}');
-- For NCHAR and NVARCHAR2 literals, use the prefix nq instead of q.
where_clause := q'{where col_value like '%e'}';
END;
DECLARE
d1 DATE := DATE '1998-12-25';
t1 TIMESTAMP := TIMESTAMP '1997-10-22 13:01:01';
t2 TIMESTAMP WITH TIME ZONE := TIMESTAMP '1997-01-31 09:26:56.66 +02:00';
-- Three years and two months
-- (For greater precision, we would use the day-to-second interval)
i1 INTERVAL YEAR TO MONTH := INTERVAL '3-2' YEAR TO MONTH;
-- Five days, four hours, three minutes, two and 1/100 seconds
i2 INTERVAL DAY TO SECOND := INTERVAL '5 04:03:02.01' DAY TO SECOND;
BEGIN
NULL;
END;
DECLARE
some_condition BOOLEAN;
pi NUMBER := 3.1415926;
radius NUMBER := 15;
area NUMBER;
BEGIN
/* Perform some simple tests and assignments */
IF 2 + 2 = 4 THEN
some_condition := TRUE; /* We expect this THEN to always be done */
END IF;
/*
The following line computes the area of a
circle using pi, which is the ratio between
the circumference and diameter.
*/
area := pi * radius ** 2;
END;
DECLARE
credit_limit CONSTANT REAL := 5000.00;
max_days_in_year CONSTANT INTEGER := 366;
urban_legend CONSTANT BOOLEAN := FALSE;
hours_worked INTEGER DEFAULT 40;
employee_count INTEGER := 0;
acct_id INTEGER(4) NOT NULL := 9999;
credit NUMBER(7, 2);
debit credit%TYPE;
NAME VARCHAR2(20) := 'JoHn SmItH';
-- If we increase the length of NAME, the other variables
-- become longer too.
upper_name NAME%TYPE := UPPER(NAME);
lower_name NAME%TYPE := LOWER(NAME);
init_name NAME%TYPE := INITCAP(NAME);
the_trigger user_triggers.trigger_name%TYPE;
my_empno employees.employee_id%TYPE;
-- %ROWTYPE can include all the columns in a table...
emp_rec employees%ROWTYPE;
-- ...or a subset of the columns, based on a cursor.
CURSOR c1 IS
SELECT department_id, department_name FROM departments;
dept_rec c1%ROWTYPE;
-- Could even make a %ROWTYPE with columns from multiple tables.
CURSOR c2 IS
SELECT employee_id, email, employees.manager_id, location_id FROM employees, departments
WHERE employees.department_id = departments.department_id;
join_rec c2%ROWTYPE;
BEGIN
-- We know EMP_REC can hold a row from the EMPLOYEES table.
SELECT * INTO emp_rec FROM employees
WHERE ROWNUM < 2;
-- We can refer to the fields of EMP_REC using column names
-- from the EMPLOYEES table.
IF emp_rec.department_id = 20 AND emp_rec.last_name = 'JOHNSON' THEN
emp_rec.salary := emp_rec.salary * 1.15;
END IF;
END;
DECLARE
dept_rec1 departments%ROWTYPE;
dept_rec2 departments%ROWTYPE;
CURSOR c1 IS
SELECT department_id, location_id FROM departments;
dept_rec3 c1%ROWTYPE;
BEGIN
dept_rec1 := dept_rec2; -- allowed
-- dept_rec2 refers to a table, dept_rec3 refers to a cursor
-- dept_rec2 := dept_rec3; -- not allowed
END;
DECLARE
dept_rec departments%ROWTYPE;
BEGIN
SELECT * INTO dept_rec FROM departments
WHERE department_id = 30 AND ROWNUM < 2;
END;
BEGIN
-- We assign an alias (COMPLETE_NAME) to the expression value, because
-- it has no column name.
FOR item IN
(SELECT first_name || ' ' || last_name complete_name FROM employees
WHERE ROWNUM < 11)
LOOP
-- Now we can refer to the field in the record using this alias.
dbms_output.put_line('Employee name: ' || item.complete_name);
END LOOP;
END;
-- CREATE TABLE employees2 AS SELECT last_name FROM employees;
<< MAIN >>
DECLARE
last_name VARCHAR2(10) := 'King';
my_last_name VARCHAR2(10) := 'King';
BEGIN
-- Deletes everyone, because both LAST_NAMEs refer to the column
DELETE FROM employees2
WHERE last_name = last_name;
dbms_output.put_line('Deleted ' || SQL%ROWCOUNT || ' rows.');
ROLLBACK;
-- OK, column and variable have different names
DELETE FROM employees2
WHERE last_name = my_last_name;
dbms_output.put_line('Deleted ' || SQL%ROWCOUNT || ' rows.');
ROLLBACK;
-- OK, block name specifies that 2nd LAST_NAME is a variable
DELETE FROM employees2
WHERE last_name = main.last_name;
dbms_output.put_line('Deleted ' || SQL%ROWCOUNT || ' rows.');
ROLLBACK;
END;
-- DROP TABLE employees2;
DECLARE
FUNCTION dept_name(department_id IN NUMBER)
RETURN departments.department_name%TYPE IS
department_name departments.department_name%TYPE;
BEGIN
-- DEPT_NAME.DEPARTMENT_NAME specifies the local variable
-- instead of the table column
SELECT department_name INTO dept_name.department_name FROM departments
WHERE department_id = dept_name.department_id;
RETURN department_name;
END;
BEGIN
FOR item IN
(SELECT department_id FROM departments)
LOOP
dbms_output.put_line('Department: ' || dept_name(item.department_id));
END LOOP;
END;
DECLARE
a CHAR;
b REAL;
BEGIN
-- identifiers available here: a (CHAR), b
DECLARE
a INTEGER;
c REAL;
BEGIN
-- identifiers available here: a (INTEGER), b, c
NULL;
END;
DECLARE
d REAL;
BEGIN
-- identifiers available here: a (CHAR), b, d
NULL;
END;
-- identifiers available here: a (CHAR), b
END;
<< outer >>
DECLARE
birthdate DATE;
BEGIN
DECLARE
birthdate DATE;
BEGIN
IF birthdate = outer.birthdate THEN
NULL;
END IF;
END;
END;
PROCEDURE check_credit(xxx REAL) IS
rating NUMBER;
FUNCTION valid(xxx REAL)
RETURN BOOLEAN IS
rating NUMBER;
BEGIN
IF check_credit.rating < 3 THEN
NULL;
END IF;
END;
BEGIN
NULL;
END;
DECLARE
counter INTEGER;
BEGIN
-- COUNTER is initially NULL, so 'COUNTER + 1' is also null.
counter := counter + 1;
IF counter IS NULL THEN
dbms_output.put_line('Sure enough, COUNTER is NULL not 1.');
END IF;
END;
DECLARE
done BOOLEAN; -- DONE is initially NULL
counter NUMBER := 0;
BEGIN
done := FALSE; -- Assign a literal value
WHILE done != TRUE -- Compare to a literal value
LOOP
counter := counter + 1;
done := (counter > 500); -- If counter > 500, DONE = TRUE
END LOOP;
END;
DECLARE
emp_id employees.employee_id%TYPE := 100;
emp_name employees.last_name%TYPE;
wages NUMBER(7, 2);
BEGIN
SELECT last_name, salary + (salary * nvl(commission_pct, 0)) INTO emp_name, wages FROM employees
WHERE employee_id = emp_id;
dbms_output.put_line('Employee ' || emp_name || ' might make ' || wages);
END;
DECLARE
on_hand INTEGER := 0;
on_order INTEGER := 100;
BEGIN
-- Does not cause divide-by-zero error; evaluation stops after 1st expr.
IF (on_hand = 0) OR ( (on_order / on_hand) < 5) THEN
dbms_output.put_line('There are no more widgets left!');
END IF;
END;
DECLARE
PROCEDURE assert(assertion VARCHAR2,
truth BOOLEAN) IS
BEGIN
IF truth IS NULL THEN
dbms_output.put_line('Assertion ' || assertion || ' is unknown (NULL)');
ELSIF truth = TRUE THEN
dbms_output.put_line('Assertion ' || assertion || ' is TRUE');
ELSE
dbms_output.put_line('Assertion ' || assertion || ' is FALSE');
END IF;
END;
BEGIN
assert('2 + 2 = 4', 2 + 2 = 4);
assert('10 > 1', 10 > 1);
assert('10 <= 1', 10 <= 1);
assert('5 BETWEEN 1 AND 10', 5 BETWEEN 1 AND 10);
assert('NULL != 0', NULL != 0);
assert('3 IN (1,3,5)', 3 IN (1, 3, 5));
assert(q'{'A'\r\n < 'Z'}', 'A' < 'Z');
assert(q'{'baseball' LIKE '%all%'}', 'baseball' LIKE '%all%');
assert(q'{'suit' || 'case' = 'suitcase'}', 'suit' || 'case' = 'suitcase');
END;
DECLARE
fraction BINARY_FLOAT := 1 / 3;
BEGIN
IF fraction = 11 / 33 THEN
dbms_output.put_line('Fractions are equal (luckily!)');
END IF;
END;
DECLARE
done BOOLEAN;
BEGIN
-- Each WHILE loop is equivalent
done := FALSE;
WHILE done = FALSE LOOP
done := TRUE;
END LOOP;
done := FALSE;
WHILE NOT (done = TRUE) LOOP
done := TRUE;
END LOOP;
done := FALSE;
WHILE NOT done LOOP
done := TRUE;
END LOOP;
END;
DECLARE
grade CHAR(1) := 'B';
appraisal VARCHAR2(20);
BEGIN
appraisal := CASE grade
WHEN 'A' THEN 'Excellent'
WHEN 'B' THEN 'Very Good'
WHEN 'C' THEN 'Good'
WHEN 'D' THEN 'Fair'
WHEN 'F' THEN 'Poor'
ELSE 'No such grade'
END;
dbms_output.put_line('Grade ' || grade || ' is ' || appraisal);
END;
DECLARE
grade CHAR(1) := 'B';
appraisal VARCHAR2(120);
id NUMBER := 8429862;
attendance NUMBER := 150;
min_days CONSTANT NUMBER := 200;
FUNCTION attends_this_school(id NUMBER)
RETURN BOOLEAN IS
BEGIN
RETURN TRUE;
END;
BEGIN
appraisal := CASE
WHEN attends_this_school(id) = FALSE THEN 'N/A - Student not enrolled'
-- Have to put this condition early to detect
-- good students with bad attendance
WHEN grade = 'F' OR attendance < min_days THEN 'Poor (poor performance or bad attendance)'
WHEN grade = 'A' THEN 'Excellent'
WHEN grade = 'B' THEN 'Very Good'
WHEN grade = 'C' THEN 'Good'
WHEN grade = 'D' THEN 'Fair'
ELSE 'No such grade'
END;
dbms_output.put_line('Result for student ' || id || ' is ' || appraisal);
END;
DECLARE
x NUMBER := 5;
y NUMBER := NULL;
BEGIN
IF x != y THEN -- yields NULL, not TRUE
dbms_output.put_line('x != y'); -- not executed
ELSIF x = y THEN -- also yields NULL
dbms_output.put_line('x = y');
ELSE
dbms_output.put_line(q'{Can't tell if x and y are equal or not...}');
END IF;
END;
DECLARE
a NUMBER := NULL;
b NUMBER := NULL;
BEGIN
IF a = b THEN -- yields NULL, not TRUE
dbms_output.put_line('a = b'); -- not executed
ELSIF a != b THEN -- yields NULL, not TRUE
dbms_output.put_line('a != b'); -- not executed
ELSE
dbms_output.put_line(q'{Can't tell if two NULLs are equal}');
END IF;
END;
DECLARE
null_string VARCHAR2(80) := TO_CHAR('');
address VARCHAR2(80);
zip_code VARCHAR2(80) := SUBSTR(address, 25, 0);
NAME VARCHAR2(80);
valid BOOLEAN := (NAME != '');
BEGIN
NULL;
END;
DECLARE
the_manager VARCHAR2(40);
NAME employees.last_name%TYPE;
BEGIN
-- NULL is a valid argument to DECODE. In this case, manager_id is null
-- and the DECODE function returns 'nobody'.
SELECT DECODE (manager_id, NULL, 'nobody', 'somebody'), last_name INTO the_manager, NAME FROM employees
WHERE employee_id = 100;
dbms_output.put_line(NAME || ' is managed by ' || the_manager);
END;
DECLARE
string_type VARCHAR2(60);
old_string string_type%TYPE := 'Apples and oranges';
my_string string_type%TYPE := 'more apples';
-- NULL is a valid argument to REPLACE, but does not match
-- anything so no replacement is done.
new_string string_type%TYPE := REPLACE (old_string, NULL, my_string);
BEGIN
dbms_output.put_line('Old string = ' || old_string);
dbms_output.put_line('New string = ' || new_string);
END;
DECLARE
string_type VARCHAR2(60);
dashed string_type%TYPE := 'Gold-i-locks';
-- When the substitution text for REPLACE is NULL,
-- the text being replaced is deleted.
NAME string_type%TYPE := REPLACE (dashed, '-', NULL);
BEGIN
dbms_output.put_line('Dashed name = ' || dashed);
dbms_output.put_line('Dashes removed = ' || NAME);
END;
PL/SQL Code after Obfuscation
Notice that comments are gone, names have been scrambled. The obfuscator uses a special list provided by the user to define names that should be preserved, ensuring that public interfaces and accesses to public libraries remain valid. If you obfuscate a set of PL/SQL source files simultaneously, only the public symbols they collectively offer will be sensibly named in the source files.
declare
Oil100 number(4);
iil101 boolean;
Oil10i real(7, 2);
iil10i constant number := 5000.00;
Oil10l iil110.Oil111%type;
iil111 Oil11i%rowtype;
iil11l Oil1i0%rowtype;
iil1i0 number(11, 2);
Oil1i1 constant number(4) := 3;
iil1ii constant number(5, 2) := 500.00;
begin
Oil1il := iil1il * Oil1l0;
iil1l1 := false;
Oil1li := iil1li * 0.10;
Oil1ll := iili00(Oili01, iili01, Oili0i) - iili0l;
select Oili10, iili10, Oili11, iili1i from Oili1l;
select iili1l * 0.10 into Oil1li from Oilii0
where iilii1 = Oili01;
select Oiliii(iili10) into Oil10i from Oili1l;
iiliii(7788, Oil10i);
for Oiliil in
(select * from Oilii0)
loop
iilil0.Oilil1('First name = ' || Oiliil.iilil1);
iilil0.Oilil1('Last name = ' || Oiliil.Oilili);
end loop;
iilill := iil111.Oill00;
fetch Oil1i0 into iil11l;
select iill00 into iil1i0 from Oill01
where iill0i = Oil1i1
for update of iill00;
if iil1i0 >= iil1ii then
update Oill01
set iill00 = iill00 - iil1ii
where iill0i = Oil1i1;
else
insert into Oill0l
values (Oil1i1, iil1i0, 'Insufficient funds');
end if;
commit;
case
when iill0l = 'square' then
Oill10 := iill11 * iill11;
when iill0l = 'circle' then
begin
Oill10 := Oill1i * (iill1i * iill1i);
iilil0.Oilil1('Value is not exact because pi is irrational.');
end;
when iill0l = 'rectangle' then
Oill10 := length * Oill1l;
else
begin
iilil0.Oilil1('No formula to calculate area of a' || iill0l);
raise iilli0;
end;
end case;
for Oilli1 in 1 .. 500 loop
insert into iilli1
values (Oilli1, Oillii(Oilli1));
end loop;
end;
declare
iili1l Oili1l.iili10%type := 0;
iillil Oili1l.Oilll0%type;
Oilili Oili1l.Oili10%type;
iilll0 Oili1l.Oilll1%type := 7499;
begin
select Oilll0 into iillil from Oili1l
where Oilll1 = iilll0;
while iili1l <= 2500 loop
select iili10, Oilll0, Oili10 into iili1l, iillil, Oilili from Oili1l
where Oilll1 = iillil;
end loop;
insert into Oill0l
values (null, iili1l, Oilili);
commit;
exception
when iillli then
insert into Oill0l
values (null, null, 'Not found');
commit;
end;
declare
procedure Oillll(Oili01 number) is
Oil1li real;
iillll exception;
begin
select ll0000 * 0.15 into Oil1li from Oili1l
where Oilll1 = Oili01;
if Oil1li is null then
raise iillll;
else
update Ol0000
set il0001 = il0001 + Oil1li
where Oilll1 = Oili01;
end if;
exception
when iillll then
commit;
end Oillll;
begin
Oil1li := 1.0;
end;
create package ll0001 as
procedure Ol000i(Oilll1 number,
Oili10 char);
procedure il000i(Oili01 number);
end ll0001;
create package body ll0001 as
procedure Ol000i(Oilll1 number,
Oili10 char) is
begin
insert into Oili1l
values (Oilll1, Oili10);
end Ol000i;
procedure il000i(Oili01 number) is
begin
delete from Oili1l
where Oilll1 = Oili01;
end il000i;
end ll0001;
declare
type ll000l is table of Ol000l;
il0010 Ol000l;
function ll0010(Oili11 date)
return ll000l is
begin
null;
end;
begin
il0010 := ll0010('10-NOV-98') (5);
end;
declare
type Ol0011 is
record (il0011 smallint,
ll001i smallint);
type Ol001i is
record (il001l date,
ll001l Ol0011,
Ol00i0 varchar2(20),
il00i0 varchar2(50));
begin
null;
end;
create type ll00i1 as
object (Ol00i1 integer(5),
il00ii real,
ll00ii varchar2(10),
member procedure open(Ol00il in real),
member procedure il00il(Oilli1 in integer),
member procedure close(Oilli1 in integer,
Ol00il out real),
member procedure ll00l0(Oilli1 in integer,
Ol00il in real),
member procedure Ol00l0(Oilli1 in integer,
Ol00il in real),
member function il00l1(Oilli1 in integer)
return real);
declare
iillll exception;
begin
if ll00l1 is null then
raise iillll;
end if;
Oil1li := (iili1l * 0.10) + (ll00l1 * 0.15);
exception
when iillll then
null;
end;
declare
Ol00li number;
begin
Ol00li := 10E127;
end;
declare
il00li binary_float := ll00ll(2.0);
Ol00ll binary_double := ll00ll(2.0);
begin
null;
end;
begin
il0100 := 'Hello, world!';
il0100 := 'XYZ Corporation';
il0100 := '10-NOV-91';
il0100 := 'He said "Life is like licking honey from a thorn."';
il0100 := '$1,000,000';
il0100 := 'I''m a string, you''re a string.';
ll0100 := 'I''m a string, you''re a string.';
Ol0101('select index_name from user_indexes where status = ''INVALID''');
il0101 := 'where col_value like ''%é''';
end;
declare
ll010i date := date '1998-12-25';
Ol010i timestamp := timestamp '1997-10-22 13:01:01';
il010l timestamp with time zone := timestamp '1997-01-31 09:26:56.66 +02:00';
ll010l interval year to month := interval '3-2' year to month;
Ol0110 interval day to second := interval '5 04:03:02.01' day to second;
begin
null;
end;
declare
il0110 boolean;
Oill1i number := 3.1415926;
iill1i number := 15;
Oill10 number;
begin
if 2 + 2 = 4 then
il0110 := true;
end if;
Oill10 := Oill1i * iill1i ** 2;
end;
declare
iil10i constant real := 5000.00;
ll0111 constant integer := 366;
Ol0111 constant boolean := false;
il011i integer default 40;
ll011i integer := 0;
Ol011l integer(4) not null := 9999;
il011l number(7, 2);
ll01i0 il011l%type;
name varchar2(20) := 'JoHn SmItH';
Ol01i0 name%type := il01i1(name);
ll01i1 name%type := Ol01ii(name);
il01ii name%type := ll01il(name);
Ol01il il01l0.ll01l0%type;
Ol01l1 Oilii0.iilii1%type;
iil11l Oilii0%rowtype;
cursor Oil1i0 is
select il01l1, ll01li from Ol01li;
iil111 Oil1i0%rowtype;
cursor il01ll is
select iilii1, ll01ll, Oilii0.Ol0i00, il0i00 from Oilii0, Ol01li
where Oilii0.il01l1 = Ol01li.il01l1;
ll0i01 il01ll%rowtype;
begin
select * into iil11l from Oilii0
where Ol0i01 < 2;
if iil11l.il01l1 = 20 and iil11l.Oilili = 'JOHNSON' then
iil11l.iili1l := iil11l.iili1l * 1.15;
end if;
end;
declare
il0i0i Ol01li%rowtype;
ll0i0i Ol01li%rowtype;
cursor Oil1i0 is
select il01l1, il0i00 from Ol01li;
Ol0i0l Oil1i0%rowtype;
begin
il0i0i := ll0i0i;
end;
declare
iil111 Ol01li%rowtype;
begin
select * into iil111 from Ol01li
where il01l1 = 30 and Ol0i01 < 2;
end;
begin
for il0i0l in
(select iilil1 || ' ' || Oilili ll0i10 from Oilii0
where Ol0i01 < 11)
loop
Ol0i10.il0i11('Employee name: ' || il0i0l.ll0i10);
end loop;
end;
<< main >>
declare
Oilili varchar2(10) := 'King';
ll0i11 varchar2(10) := 'King';
begin
delete from Ol0i1i
where Oilili = Oilili;
Ol0i10.il0i11('Deleted ' || sql%rowcount || ' rows.');
rollback;
delete from Ol0i1i
where Oilili = ll0i11;
Ol0i10.il0i11('Deleted ' || sql%rowcount || ' rows.');
rollback;
delete from Ol0i1i
where Oilili = main.Oilili;
Ol0i10.il0i11('Deleted ' || sql%rowcount || ' rows.');
rollback;
end;
declare
function il0i1i(il01l1 in number)
return Ol01li.ll01li%type is
ll01li Ol01li.ll01li%type;
begin
select ll01li into il0i1i.ll01li from Ol01li
where il01l1 = il0i1i.il01l1;
return ll01li;
end;
begin
for il0i0l in
(select il01l1 from Ol01li)
loop
Ol0i10.il0i11('Department: ' || il0i1i(il0i0l.il01l1));
end loop;
end;
declare
ll0i1l char;
Ol0i1l real;
begin
declare
ll0i1l integer;
il0ii0 real;
begin
null;
end;
declare
ll0ii0 real;
begin
null;
end;
end;
<< outer >>
declare
Ol0ii1 date;
begin
declare
Ol0ii1 date;
begin
if Ol0ii1 = outer.Ol0ii1 then
null;
end if;
end;
end;
procedure il0ii1(ll0iii real) is
Ol0iii number;
function il0iil(ll0iii real)
return boolean is
Ol0iii number;
begin
if il0ii1.Ol0iii < 3 then
null;
end if;
end;
begin
null;
end;
declare
ll0iil integer;
begin
ll0iil := ll0iil + 1;
if ll0iil is null then
Ol0i10.il0i11('Sure enough, COUNTER is NULL not 1.');
end if;
end;
declare
Ol0il0 boolean;
ll0iil number := 0;
begin
Ol0il0 := false;
while Ol0il0 != true loop
ll0iil := ll0iil + 1;
Ol0il0 := (ll0iil > 500);
end loop;
end;
declare
Oili01 Oilii0.iilii1%type := 100;
il0il0 Oilii0.Oilili%type;
Oil1ll number(7, 2);
begin
select Oilili, iili1l + (iili1l * ll0il1(Ol0il1, 0)) into il0il0, Oil1ll from Oilii0
where iilii1 = Oili01;
Ol0i10.il0i11('Employee ' || il0il0 || ' might make ' || Oil1ll);
end;
declare
il0ili integer := 0;
ll0ili integer := 100;
begin
if (il0ili = 0) or ( (ll0ili / il0ili) < 5) then
Ol0i10.il0i11('There are no more widgets left!');
end if;
end;
declare
procedure Ol0ill(il0ill varchar2,
ll0l00 boolean) is
begin
if ll0l00 is null then
Ol0i10.il0i11('Assertion ' || il0ill || ' is unknown (NULL)');
elsif ll0l00 = true then
Ol0i10.il0i11('Assertion ' || il0ill || ' is TRUE');
else
Ol0i10.il0i11('Assertion ' || il0ill || ' is FALSE');
end if;
end;
begin
Ol0ill('2 + 2 = 4', 2 + 2 = 4);
Ol0ill('10 > 1', 10 > 1);
Ol0ill('10 <= 1', 10 <= 1);
Ol0ill('5 BETWEEN 1 AND 10', 5 between 1 and 10);
Ol0ill('NULL != 0', null != 0);
Ol0ill('3 IN (1,3,5)', 3 in (1, 3, 5));
Ol0ill('''A'' < ''Z''', 'A' < 'Z');
Ol0ill('''baseball'' LIKE ''%all%''', 'baseball' like '%all%');
Ol0ill('''suit'' || ''case'' = ''suitcase''', 'suit' || 'case' = 'suitcase');
end;
declare
Ol0l00 binary_float := 1 / 3;
begin
if Ol0l00 = 11 / 33 then
Ol0i10.il0i11('Fractions are equal (luckily!)');
end if;
end;
declare
Ol0il0 boolean;
begin
Ol0il0 := false;
while Ol0il0 = false loop
Ol0il0 := true;
end loop;
Ol0il0 := false;
while not (Ol0il0 = true) loop
Ol0il0 := true;
end loop;
Ol0il0 := false;
while not Ol0il0 loop
Ol0il0 := true;
end loop;
end;
declare
il0l01 char(1) := 'B';
ll0l01 varchar2(20);
begin
ll0l01 := case il0l01
when 'A' then 'Excellent'
when 'B' then 'Very Good'
when 'C' then 'Good'
when 'D' then 'Fair'
when 'F' then 'Poor'
else 'No such grade'
end;
Ol0i10.il0i11('Grade ' || il0l01 || ' is ' || ll0l01);
end;
declare
il0l01 char(1) := 'B';
ll0l01 varchar2(120);
Ol0l0i number := 8429862;
il0l0i number := 150;
ll0l0l constant number := 200;
function Ol0l0l(Ol0l0i number)
return boolean is
begin
return true;
end;
begin
ll0l01 := case
when Ol0l0l(Ol0l0i) = false then 'N/A - Student not enrolled'
when il0l01 = 'F' or il0l0i < ll0l0l then 'Poor (poor performance or bad attendance)'
when il0l01 = 'A' then 'Excellent'
when il0l01 = 'B' then 'Very Good'
when il0l01 = 'C' then 'Good'
when il0l01 = 'D' then 'Fair'
else 'No such grade'
end;
Ol0i10.il0i11('Result for student ' || Ol0l0i || ' is ' || ll0l01);
end;
declare
il00li number := 5;
Ol00ll number := null;
begin
if il00li != Ol00ll then
Ol0i10.il0i11('x != y');
elsif il00li = Ol00ll then
Ol0i10.il0i11('x = y');
else
Ol0i10.il0i11('Can''t tell if x and y are equal or not...');
end if;
end;
declare
ll0i1l number := null;
Ol0i1l number := null;
begin
if ll0i1l = Ol0i1l then
Ol0i10.il0i11('a = b');
elsif ll0i1l != Ol0i1l then
Ol0i10.il0i11('a != b');
else
Ol0i10.il0i11('Can''t tell if two NULLs are equal');
end if;
end;
declare
il0l10 varchar2(80) := ll0l10('');
Ol0l11 varchar2(80);
il0l11 varchar2(80) := ll0l1i(Ol0l11, 25, 0);
name varchar2(80);
il0iil boolean := (name != '');
begin
null;
end;
declare
Ol0l1i varchar2(40);
name Oilii0.Oilili%type;
begin
select decode(Ol0i00, null, 'nobody', 'somebody'), Oilili into Ol0l1i, name from Oilii0
where iilii1 = 100;
Ol0i10.il0i11(name || ' is managed by ' || Ol0l1i);
end;
declare
il0l1l varchar2(60);
ll0l1l il0l1l%type := 'Apples and oranges';
Ol0li0 il0l1l%type := 'more apples';
il0li0 il0l1l%type := replace(ll0l1l, null, Ol0li0);
begin
Ol0i10.il0i11('Old string = ' || ll0l1l);
Ol0i10.il0i11('New string = ' || il0li0);
end;
declare
il0l1l varchar2(60);
ll0li1 il0l1l%type := 'Gold-i-locks';
name il0l1l%type := replace(ll0li1, '-', null);
begin
Ol0i10.il0i11('Dashed name = ' || ll0li1);
Ol0i10.il0i11('Dashes removed = ' || name);
end;
Obfuscated Symbol Cross Reference
The obfuscator produces a cross reference mapping obfuscated symbols to the orginal symbols, so that obfuscated code in the field can still be decoded if necessary. In fact, by reversing this map, the obfuscator can unobfuscate the code (of course, it cannot restore the comments). Of course, you can only do this, if you have the map.
### Obfuscated Identifiers ### AVG -> Oiliii Bank_Account -> ll00i1 DBMS_OUTPUT -> iilil0 Employee -> Ol000l INITCAP -> ll01il LOWER -> Ol01ii MeetingTyp -> Ol001i NO_DATA_FOUND -> iillli PROGRAM_ERROR -> iilli0 PUT_LINE -> Oilil1 ROWNUM -> Ol0i01 SQRT -> Oillii SUBSTR -> ll0l1i Staff -> ll000l TO_CHAR -> ll0l10 TimeRec -> Ol0011 UPPER -> il01i1 a -> ll0i1l account_id -> iill0i accounts -> Oill01 acct -> Oil1i1 acct_balance -> iil1i0 acct_id -> Ol011l acct_number -> Ol00i1 address -> Ol0l11 adjust_salary -> iiliii amount -> Ol00il appraisal -> ll0l01 area -> Oill10 assert -> Ol0ill assertion -> il0ill attendance -> il0l0i attends_this_school -> Ol0l0l award_bonus -> Oillll b -> Ol0i1l bal -> iill00 balance -> il00ii birthdate -> Ol0ii1 bonus -> Oil1li books -> iil110 c -> il0ii0 c1 -> Oil1i0 c2 -> il01ll check_credit -> il0ii1 comm -> ll0000 comm_missing -> iillll commission -> ll00l1 commission_pct -> Ol0il1 complete_name -> ll0i10 counter -> ll0iil credit -> il011l credit_limit -> iil10i curr_bal -> il00l1 current_salary -> iil1li d -> ll0ii0 d1 -> ll010i dashed -> ll0li1 date_held -> il001l dbms_output -> Ol0i10 debit -> ll01i0 debit_amt -> iil1ii deductions -> iili0l department_id -> il01l1 department_name -> ll01li departments -> Ol01li deposit -> ll00l0 dept -> Oil11i dept_name -> il0i1i dept_rec -> iil111 dept_rec1 -> il0i0i dept_rec2 -> ll0i0i dept_rec3 -> Ol0i0l deptno -> Oill00 done -> Ol0il0 duration -> ll001l email -> ll01ll emp -> Oili1l emp_actions -> ll0001 emp_id -> Oili01 emp_name -> il0il0 emp_rec -> iil11l employee_count -> ll011i employee_id -> iilii1 employees -> Oilii0 employees2 -> Ol0i1i empno -> Oilll1 ename -> Oili10 fire_employee -> il000i first_name -> iilil1 fraction -> Ol0l00 func_call -> Ol0101 grade -> il0l01 gross_pay -> iili00 hire_employee -> Ol000i hiredate -> Oili11 hours -> il0011 hours_worked -> il011i i1 -> ll010l i2 -> Ol0110 id -> Ol0l0i in_stock -> iil101 init_name -> il01ii item -> il0i0l job -> iili1i join_rec -> ll0i01 last_name -> Oilili location -> Ol00i0 location_id -> il0i00 lower_name -> ll01i1 manager_id -> Ol0i00 max_days_in_year -> ll0111 mgr -> Oilll0 mgr_num -> iillil min_days -> ll0l0l minutes -> ll001i my_deptno -> iilill my_empno -> Ol01l1 my_last_name -> ll0i11 my_sal -> Oil10i my_string -> Ol0li0 my_title -> Oil10l n -> Ol00li new_hires -> ll0010 new_string -> il0li0 null_string -> il0l10 num -> Oilli1 nvl -> ll0il1 old_string -> ll0l1l on_hand -> il0ili on_order -> ll0ili ot_hrs -> Oili0i part_no -> Oil100 pay -> il0001 payroll -> Ol0000 pi -> Oill1i price -> iil1il purpose -> il00i0 put_line -> il0i11 radius -> iill1i rating -> Ol0iii roots -> iilli1 sal -> iili10 salary -> iili1l shape -> iill0l side -> iill11 some_condition -> il0110 someone -> Oiliil sqrt -> ll00ll st_hrs -> iili01 staffer -> il0010 starting_empno -> iilll0 status -> ll00ii str -> il0100 string_type -> il0l1l string_var -> ll0100 t1 -> Ol010i t2 -> il010l tax -> Oil1il tax_rate -> Oil1l0 temp -> Oill0l the_manager -> Ol0l1i the_trigger -> Ol01il title -> Oil111 trigger_name -> ll01l0 truth -> ll0l00 upper_name -> Ol01i0 urban_legend -> Ol0111 user_triggers -> il01l0 valid -> il0iil valid_id -> iil1l1 verify_acct -> il00il wages -> Oil1ll where_clause -> il0101 width -> Oill1l withdraw -> Ol00l0 x -> il00li xxx -> ll0iii y -> Ol00ll zip_code -> il0l11
Copyright © 1995-2008 Semantic Designs, Incorporated
DMS and "Design Maintenance System" are registered trademarks of Semantic Designs, Inc.
The SD logo and "Semantic Designs" are registered service marks of Semantic Designs, Inc.
CloneDR, PARLANSE and Thicket are trademarks of Semantic Designs, Inc.
The OMG logo is a registered trademark of the Object Management Group, Inc. in the United States and other countries.
To view our Privacy Policy, click here
Comments or problems: webmaster@semdesigns.com
