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;
/
相关推荐
刘一说10 小时前
Java 中实现多租户架构:数据隔离策略与实践指南
java·oracle·架构
tryCbest10 小时前
Oracle查看存储过程
数据库·oracle
IT邦德11 小时前
OEL9.7 安装 Oracle 26ai RAC
数据库·oracle
Goat恶霸詹姆斯1 天前
mysql常用语句
数据库·mysql·oracle
xiaowu0801 天前
C# 拆解 “显式接口实现 + 子类强类型扩展” 的设计思想
数据库·oracle
Apple_羊先森1 天前
ORACLE数据库巡检SQL脚本--19、磁盘读次数最高的前5条SQL语句
数据库·sql·oracle
蚕豆哥1 天前
【2026马年重启】我的 Primavera P6/Unifier 技术笔记,继续更新!
ai·oracle·项目管理·unifier·p6·进度管理·甲骨文
认真的薛薛1 天前
数据库-sql语句
数据库·sql·oracle
IT邦德1 天前
RPM包快速安装Oracle26ai
数据库·oracle
穿过锁扣的风1 天前
一文搞懂 SQL 五大分类:DQL/DML/DDL/DCL/TCL
数据库·microsoft·oracle