--=============================
-- PL/SQL --> DBMS_DDL包的使用
--=============================
为了便于建立性能良好的PL/SQL程序,Oracle提供了大量的系统包供使用。Oracle提供的这些包扩展并增强了数据库的一些功能,以及突
破了PL/SQL的一些限制。本文讲述了Oracle提供的包DBMS_DDL,以及其使用方法。
一、 使用DBMS_DDL包可以对包,包体,存储过程,函数,触发器等等进行编译,以及为数据库对象提供一些统计信息。
下面列出几个常用的过程
1.ALTER_COMPILE --编译对象
PROCEDURE DBMS_DDL.ALTER_COMPILE
(type IN VARCHAR2 --PROCEDURE, FUNCTION, PACKAGE, PACKAGE BODY or TRIGGER.
,schema IN VARCHAR2
,name IN VARCHAR2);
与之相等的操作:ALTER PROCEDURE | FUNCTION | PACKAGE [<schema>.] <name> COMPILE [BODY]
--下面创建一个过程来对数据库中特定用户的无效对象进行重新编译
CREATE OR REPLACE PROCEDURE recompile
(status_in IN VARCHAR2 := 'INVALID',
name_in IN VARCHAR2 := '%',
type_in IN VARCHAR2 := '%',
schema_in IN VARCHAR2 := USER)
IS
v_objtype VARCHAR2(100);
err_status NUMERIC;
CURSOR obj_cur IS
SELECT owner, object_name, object_type
FROM ALL_OBJECTS
WHERE status LIKE UPPER (status_in)
AND object_name LIKE UPPER (name_in)
AND object_type LIKE UPPER (type_in)
AND owner LIKE UPPER (schema_in)
ORDER BY
DECODE (object_type,
'PACKAGE', 1,
'FUNCTION', 2,
'PROCEDURE', 3,
'PACKAGE BODY', 4);
BEGIN
FOR rec IN obj_cur
LOOP
IF rec.object_type = 'PACKAGE'
THEN
v_objtype := 'PACKAGE SPECIFICATION';
ELSE
v_objtype := rec.object_type;
END IF;
DBMS_DDL.ALTER_COMPILE (v_objtype, rec.owner, rec.object_name);
DBMS_OUTPUT.PUT_LINE
('Compiled ' || v_objtype || ' of ' ||
rec.owner || '.' || rec.object_name);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
BEGIN
err_status := SQLCODE;
DBMS_OUTPUT.PUT_LINE(' Recompilation failed : ' || SQLERRM(err_status));
IF ( obj_cur%ISOPEN) THEN
CLOSE obj_cur;
END IF;
END;
END;
scott@ORCL> exec recompile(schema_in=>'SCOTT');
Compiled FUNCTION of SCOTT.F_NEGATIVE
Compiled PROCEDURE of SCOTT.COMPUTE
Compiled TRIGGER of SCOTT.E_D
PL/SQL procedure successfully completed.
2.ANALYZE_OBJECT --收集表,索引,簇等的统计信息
PROCEDURE DBMS_DDL.ANALYZE_OBJECT
(type IN VARCHAR2 --TABLE, CLUSTER or INDEX
,schema IN VARCHAR2
,name IN VARCHAR2
,method IN VARCHAR2 --ESTIMATE, COMPUTE or DELETE
,estimate_rows IN NUMBER DEFAULT NULL
,estimate_percent IN NUMBER DEFAULT NULL
,method_opt IN VARCHAR2 DEFAULT NULL) --[FOR TABLE ][ FOR ALL [INDEXED] COLUMNS] [SIZE n][ FOR ALL INDEXES ]
,partname IN VARCHAR2 DEFAULT NULL);
与之相等的操作:ANALYZE TABLE|CLUSTER|INDEX [<schema>.]<name> [<method>] STATISTICS [SAMPLE <n> [ROWS|PERCENT]]
scott@ORCL> exec dbms_ddl.analyze_object('TABLE','SCOTT','EMP','ESTIMATE');
PL/SQL procedure successfully completed.
3.DBMS_DDL.WRAP --使用wrap函数可以加密子程序
该函数使用了3个重载函数,即可以使用3种不同的方式来对子程序进行动态加密
DBMS_DDL.WRAP( --方式一
ddl VARCHAR2) --接收VARCHAR2类型的输入
RETURN VARCHAR2;
DBMS_DDL.WRAP( --方式二
ddl DBMS_SQL.VARCHAR2S, --允许大的DDL语句的输入,dbms_sql.varchar2s限制为每行256字节
lb PLS_INTEGER,
ub PLS_INTEGER)
RETURN DBMS_SQL.VARCHAR2S;
DBMS_DDL.WRAP( --方式三
ddl DBMS_SQL.VARCHAR2A, --允许大的DDL语句的输入,dbms_sql.varchar2a为每行32767字节
lb PLS_INTEGER,
ub PLS_INTEGER)
RETURN DBMS_SQL.VARCHAR2A;
ddl:入参ddl要求语法为”create or replace…”的字符串,用以创建包、包体、类型、类型体、函数和过程的程序单元的DDL语句
。如果入参ddl所定义的程序单元不能被加密,或存在语法错误,则将抛出“MALFORMED_WRAP_INPUT”异常。
lb:为加密集合的最低元素
ub:为加密集合的最高元素
返回值:为加密后的代码。可以将它写入一个文件中,或者存储在表中。
--使用简单方式实现加密,使用方式一
SET SERVEROUTPUT ON SIZE UNLIMITED
DECLARE
l_source VARCHAR2(32767);
l_wrap VARCHAR2(32767);
BEGIN
l_source := 'CREATE OR REPLACE FUNCTION get_date_string RETURN VARCHAR2 AS' ||
'BEGIN ' ||
'RETURN TO_CHAR(SYSDATE, ''DD-MON-YYYY''); ' ||
'END get_date_string;';
l_wrap := SYS.DBMS_DDL.WRAP(ddl => l_source);
DBMS_OUTPUT.put_line(l_wrap);
END;
CREATE OR REPLACE FUNCTION get_date_string wrapped
a000000
1f
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
8
6e 96
Mm0XeMkyhwPRoFPms2i+maxm+XAwg0xff8upynSmEPJ4IfeVjSbm6TkMCRi9trW1Am