PL/SQL11——DBMS_DDL包的使用

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介:  http://blog.csdn.net/robinson_0612/article/details/6098248  为了便于建立性能良好的PL/SQL程序,Oracle提供了大量的系统包供使用。

 http://blog.csdn.net/robinson_0612/article/details/6098248

 为了便于建立性能良好的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+XAwg0xff8upynSmEPJ4IfeVjSbm6TkMCRi9trW1AmVTMIZs

            v4ABZD6CoiUcaSYfjdvzRqCeavAGromyS4qOtqqHxyw/0TtfJ0S2rO1lBTPgb1vb7rX16x0m

            LRwU

           

            对于使用DBMS_DDL.WRAP输出的密文,可以将其复制到文本文件或表中,然后将其部署到需要的地方,从一定程度上保证了代码

        的安全性。对于方式一而言,VARCHAR2(32767字节)长度限制了能够使用的PL/SQL代码长度,因此使用WRAP的两外两个重载函数可以解

        决长度缺陷问题。

 

    4.使用重载过程CREATE_WRAPPED加密子程序 

        Oracle 除了提供个重载函数WRAP实现加密之外,同时也提供了个重载过程来实现对子程序加密,有关参数描述请参考前面。

            DBMS_DDL.CREATE_WRAPPED (

               ddl     VARCHAR2);

 

            DBMS_DDL.CREATE_WRAPPED(

               ddl     DBMS_SQL.VARCHAR2A,

               lb      PLS_INTEGER,

               ub      PLS_INTEGER);

 

            DBMS_DDL.CREATE_WRAPPED(

               ddl     DBMS_SQL.VARCHAR2S,

               lb      PLS_INTEGER,

               ub      PLS_INTEGER);

              

        与函数wrap不同,过程create_wrapped不但加密源代码,而且还会在数据库中执行加密后的密文。

       

        --下面使用CREATE_WRAPPED来加密子程序

            SET SERVEROUTPUT ON SIZE UNLIMITED

            DECLARE

              l_source  DBMS_SQL.VARCHAR2A;

              l_wrap    DBMS_SQL.VARCHAR2A;

            BEGIN

              l_source(1) := 'CREATE OR REPLACE FUNCTION get_date_string RETURN VARCHAR2 AS ';

              l_source(2) := 'BEGIN ';

              l_source(3) := 'RETURN TO_CHAR(SYSDATE, ''DD-MON-YYYY''); ';

              l_source(4) := 'END get_date_string;';

             

              SYS.DBMS_DDL.CREATE_WRAPPED(ddl => l_source,

                                          lb  => 1,

                                          ub  => l_source.count);

            END;           

 

            scott@ORCL> SET PAGESIZE 100

            scott@ORCL> SELECT text     --查看加密后的密文

              2  FROM   user_source

              3  WHERE  name = 'GET_DATE_STRING'

              4  AND    type = 'FUNCTION';

 

            TEXT

            --------------------------------------------------------------------------------------

            FUNCTION get_date_string wrapped

            a000000

            1f

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            8

            6f 96

            i5ktuqFIjCuYLEse2bjmcBG7ZWgwg0xff8upynSmEPJ4IfeVjSbm6TkMCRi9trW1AmVTMB5D

            uU2KKgFAWoMdxYFR8VesyCs4U8zk9ML7b7Q+G/lGiyLbcaOIMZ4bNhIBYc2VVsvjaqr86Fu8

            VByi           

       

            scott@ORCL> select  --使用get_ddl获得加密后的密文

              2  dbms_metadata.get_ddl('FUNCTION','GET_DATE_STRING')

              3  from dual;

 

            DBMS_METADATA.GET_DDL('FUNCTION','GET_DATE_STRING')

            --------------------------------------------------------------------------------

 

              CREATE OR REPLACE FUNCTION "SCOTT"."GET_DATE_STRING" wrapped

            a000000

            1f

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            abcd

            8

            6f 96

            i5ktuqFIjCuYLEse2bjmcBG7ZWgwg0xff8upynSmEPJ4IfeVjSbm6TkMCRi9trW1AmVTMB5D

            uU2KKgFAWoMdxYFR8VesyCs4U8zk9ML7b7Q+G/lGiyLbcaOIMZ4bNhIBYc2VVsvjaqr86Fu8

            VByi       

                   

    5.DBMS_DDL.IS_TRIGGER_FIRE_ONCE 用于判断特定的触发器是否被触发过               

        DBMS_DDL.IS_TRIGGER_FIRE_ONCE(

            trig_owner  IN VARCHAR2,

            trig_name   IN VARCHAR2)

            RETURN BOOLEAN;

           

        BEGIN

          IF dbms_ddl.is_trigger_fire_once('SCOTT', 'tr_tb_a') THEN

            dbms_output.put_line('TRUE');

          ELSE

            dbms_output.put_line('FALSE');

          END IF;

        END;

       

        TRUE

相关文章
|
7月前
|
SQL Oracle 关系型数据库
Oracle的PL/SQL隐式游标:数据的“自动导游”与“轻松之旅”
【4月更文挑战第19天】Oracle PL/SQL中的隐式游标是自动管理的数据导航工具,简化编程工作,尤其适用于简单查询和DML操作。它自动处理数据访问,提供高效、简洁的代码,但不适用于复杂场景。显式游标在需要精细控制时更有优势。了解并适时使用隐式游标,能提升数据处理效率,让开发更加轻松。
|
1月前
|
SQL 数据采集 监控
局域网监控电脑屏幕软件:PL/SQL 实现的数据库关联监控
在当今网络环境中,基于PL/SQL的局域网监控系统对于企业和机构的信息安全至关重要。该系统包括屏幕数据采集、数据处理与分析、数据库关联与存储三个核心模块,能够提供全面而准确的监控信息,帮助管理者有效监督局域网内的电脑使用情况。
38 2
|
4月前
|
SQL Oracle 关系型数据库
SQL与PL/SQL:数据库编程语言的比较
【8月更文挑战第31天】
97 0
|
6月前
|
SQL 数据库 Perl
PL/SQL中执行按钮变为灰色后如何恢复【已解决】
PL/SQL中执行按钮变为灰色后如何恢复【已解决】
545 0
|
6月前
|
SQL 存储 安全
sql数据库优点,SQL数据库的优点包
SQL数据库优点概述:结构化数据存储,保证一致性和完整性;支持事务处理、数据安全机制;擅长大规模数据处理,标准化查询语言,具良好可移植性;灵活定制,支持多用户并发;具备备份恢复机制,适合数据分析和报表;拥有成熟生态系统和工具支持,广泛应用于各类场景。
71 0
|
7月前
|
SQL Oracle 关系型数据库
Oracle的PL/SQL游标属性:数据的“导航仪”与“仪表盘”
【4月更文挑战第19天】Oracle PL/SQL游标属性如同车辆的导航仪和仪表盘,提供丰富信息和控制。 `%FOUND`和`%NOTFOUND`指示数据读取状态,`%ROWCOUNT`记录处理行数,`%ISOPEN`显示游标状态。还有`%BULK_ROWCOUNT`和`%BULK_EXCEPTIONS`增强处理灵活性。通过实例展示了如何在数据处理中利用这些属性监控和控制流程,提高效率和准确性。掌握游标属性是提升数据处理能力的关键。
|
7月前
|
SQL Oracle 关系型数据库
Oracle的PL/SQL游标自定义异常:数据探险家的“专属警示灯”
【4月更文挑战第19天】Oracle PL/SQL中的游标自定义异常是处理数据异常的有效工具,犹如数据探险家的警示灯。通过声明异常名(如`LOW_SALARY_EXCEPTION`)并在满足特定条件(如薪资低于阈值)时使用`RAISE`抛出异常,能灵活应对复杂业务规则。示例代码展示了如何在游标操作中定义和捕获自定义异常,提升代码可读性和维护性,确保在面对数据挑战时能及时响应。掌握自定义异常,让数据管理更从容。
|
7月前
|
SQL Oracle 安全
Oracle的PL/SQL游标异常处理:从“惊涛骇浪”到“风平浪静”
【4月更文挑战第19天】Oracle PL/SQL游标异常处理确保了在数据操作中遇到的问题得以优雅解决,如`NO_DATA_FOUND`或`TOO_MANY_ROWS`等异常。通过使用`EXCEPTION`块捕获并处理这些异常,开发者可以防止程序因游标问题而崩溃。例如,当查询无结果时,可以显示定制的错误信息而不是让程序终止。掌握游标异常处理是成为娴熟的Oracle数据管理员的关键,能保证在复杂的数据环境中稳健运行。
|
7月前
|
SQL Oracle 关系型数据库
Oracle的PL/SQL中FOR语句循环游标的奇幻之旅
【4月更文挑战第19天】在Oracle PL/SQL中,FOR语句与游标结合,提供了一种简化数据遍历的高效方法。传统游标处理涉及多个步骤,而FOR循环游标自动处理细节,使代码更简洁、易读。通过示例展示了如何使用FOR循环游标遍历员工表并打印姓名和薪资,对比传统方式,FOR语句不仅简化代码,还因内部优化提升了执行效率。推荐开发者利用这一功能提高工作效率。
|
7月前
|
SQL Oracle 关系型数据库
Oracle的PL/SQL显式游标:数据的“私人导游”与“定制之旅”
【4月更文挑战第19天】Oracle PL/SQL中的显式游标提供灵活精确的数据访问,与隐式游标不同,需手动定义、打开、获取和关闭。通过DECLARE定义游标及SQL查询,OPEN启动查询,FETCH逐行获取数据,CLOSE释放资源。显式游标适用于复杂数据处理,但应注意SQL效率、游标管理及异常处理。它是数据海洋的私人导游,助力实现业务逻辑和数据探险。