Oracle PL/SQL 循环批量执行存储过程

1. 查询存储过程

根据数据字典USER_OBJECTS查询出所有存储过程。

2. 动态拼接字符串(参数等)

根据数据字典USER_ARGUMENTS动态拼接参数。

3. 动态执行

利用EXECUTE IMMEDIATE动态执行无名块。

4. 输出执行信息

利用DBMS_OUTPUT.PUT_LINE输出执行成功与否信息。

sql 复制代码
SET SERVEROUTPUT ON;
DECLARE
    v_sql          varchar2(32767);
    v_head         varchar2(32767);
    v_tail         varchar2(32767);
	n_count        number := 0;
    crlf           constant    varchar2(4) := chr(13) || chr(10);
BEGIN
    FOR rec1 IN (
        SELECT object_name
          FROM USER_OBJECTS
         WHERE OBJECT_TYPE = 'PROCEDURE'
         ORDER BY 1)
    LOOP
        v_sql := null;
        v_head := null;
        v_tail := null;

        ------------------------------------------
        -- Header
        ------------------------------------------
        v_head := v_head || 'DECLARE' || crlf;
        FOR rec3 IN (
            SELECT CASE data_type
                       WHEN 'DATE' THEN
                           '    d_out' || position || '    date;'
                       ELSE
                           '    v_out' || position || '    varchar2(1000);'
                   END var
              FROM user_arguments
             WHERE object_name = rec1.object_name
               AND in_out <> 'IN'
             ORDER BY position)
        LOOP
            v_head := v_head || rec3.var || crlf;
        END LOOP;
        v_head := v_head || 'BEGIN' || crlf;
        v_head := v_head || '    ' || rec1.object_name || '('  || crlf;

        ------------------------------------------
        -- Process
        ------------------------------------------
        FOR rec2 IN (
            SELECT *
              FROM user_arguments
             WHERE object_name = rec1.object_name
             ORDER BY position) 
        LOOP
            --*****************************
            -- set in parameter
            IF rec2.in_out = 'IN' then
                IF rec2.position = 1 then
                    IF rec2.data_type = 'DATE' THEN
                        v_sql := v_sql || '        ' || rec2.argument_name || ' => SYSDATE' || crlf;
                    ELSE
                        v_sql := v_sql || '        ' || rec2.argument_name || ' => 1'       || crlf;
                    END IF;
                ELSE
                    IF rec2.data_type = 'DATE' THEN
                        v_sql := v_sql || '      , ' || rec2.argument_name || ' => SYSDATE' || crlf;
                    ELSE
                        v_sql := v_sql || '      , ' || rec2.argument_name || ' => 1'       || crlf;
                    END IF;
                END IF;
            -- set out parameter
            ELSE
                 IF rec2.position = 1 then
                    IF rec2.data_type = 'DATE' THEN
                        v_sql := v_sql || '        ' || rec2.argument_name || ' => d_out' || rec2.position || crlf;
                    ELSE
                        v_sql := v_sql || '        ' || rec2.argument_name || ' => v_out' || rec2.position || crlf;
                    END IF;
                ELSE
                    IF rec2.data_type = 'DATE' THEN
                        v_sql := v_sql || '      , ' || rec2.argument_name || ' => d_out' || rec2.position || crlf;
                    ELSE
                        v_sql := v_sql || '      , ' || rec2.argument_name || ' => v_out' || rec2.position || crlf;
                    END IF;
                END IF;
            END IF;
        END LOOP;

        ------------------------------------------
        -- Tail
        ------------------------------------------
        v_tail := v_tail || '    );' || crlf;
        v_tail := v_tail || 'END;' || crlf;

        ------------------------------------------
        -- Execute SQL
        ------------------------------------------
        --dbms_output.put_line(v_head || v_sql || v_tail);
        BEGIN
			n_count := n_count + 1;
            EXECUTE IMMEDIATE v_head || v_sql || v_tail;
            DBMS_OUTPUT.PUT_LINE(LPAD(n_count, 3, '0') || '_存储过程:' || rec1.object_name || '执行成功。');
        EXCEPTION
            WHEN OTHERS THEN
                DBMS_OUTPUT.PUT_LINE(LPAD(n_count, 3, '0') ||'_存储过程:' || rec1.object_name || '执行失败。');
        END;
    END LOOP;
    ROLLBACK;
EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK;
        RAISE;
END;
/
相关推荐
Mephisto.java22 分钟前
【大数据学习 | kafka高级部分】kafka的优化参数整理
大数据·sql·oracle·kafka·json·database
BearHan3 小时前
Sqlsugar调用Oracle的存储过程
oracle·存储过程·orm
superman超哥3 小时前
04 深入 Oracle 并发世界:MVCC、锁、闩锁、事务隔离与并发性能优化的探索
数据库·oracle·性能优化·dba
Mephisto.java5 小时前
【大数据学习 | kafka高级部分】kafka的kraft集群
大数据·sql·oracle·kafka·json·hbase
Mephisto.java5 小时前
【大数据学习 | kafka高级部分】kafka的文件存储原理
大数据·sql·oracle·kafka·json
毕业设计制作和分享13 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
Dingww101118 小时前
梧桐数据库中的网络地址类型使用介绍分享
数据库·oracle·php
2401_8570262319 小时前
Spring Boot框架下的知识管理与多维分类
spring boot·后端·oracle
刘艳兵的学习博客1 天前
刘艳兵-DBA027-在Oracle数据库,通常可以使用如下方法来得到目标SQL的执行计划,那么通过下列哪些方法得到的执行计划有可能是不准确的?
数据库·oracle·面试·database·刘艳兵
秋意钟1 天前
MySql事务
数据库·mysql·oracle