首页 > 解决方案 > ORACLE 立即执行循环 ORA-06512

问题描述

我正在尝试立即执行整个 FOR 循环,但它不起作用。有可能这样做吗?

BEGIN
     FOR V_ROW IN (SELECT ROWNUM AS RN,ID AS ID FROM (SELECT ID FROM T_OPDM_PLANDEACCION WHERE IDOPORTUNIDAD=2 ORDER BY ORDEN)) LOOP UPDATE T_OPDM_PLANDEACCION SET ORDEN=V_ROW.RN WHERE ID=V_ROW.ID;END LOOP;
     EXECUTE IMMEDIATE 'FOR V_ROW IN (SELECT ROWNUM AS RN,ID AS ID FROM (SELECT ID FROM T_OPDM_PLANDEACCION WHERE IDOPORTUNIDAD=2 ORDER BY ORDEN)) LOOP UPDATE T_OPDM_PLANDEACCION SET ORDEN=V_ROW.RN WHERE ID=V_ROW.ID;END LOOP';
END;
/

第二行效果很好,但第三行(EXECUTE IMMEDIATE 'FOR V_ROW ...')不起作用。EXECUTE IMMEDIATE 中的字符串与第二行完全相同。

我需要为参数选择执行 FOR LOOP。

标签: oracleloopsfor-loopplsqlexecute

解决方案


for 循环是 PL/SQL。动态 SQL 不是。如果要动态运行 PL/SQL 代码,则需要将其放在动态语句中的 PL/SQL 块中:

BEGIN
    EXECUTE IMMEDIATE 'BEGIN FOR V_ROW IN (SELECT ROWNUM AS RN,ID AS ID FROM (SELECT ID FROM T_OPDM_PLANDEACCION WHERE IDOPORTUNIDAD=2 ORDER BY ORDEN)) LOOP UPDATE T_OPDM_PLANDEACCION SET ORDEN=V_ROW.RN WHERE ID=V_ROW.ID;END LOOP;END;';
END;

也就是说,在您拥有的内容周围添加了BEGINand (以及缺少的分号)。END;

正如@APC 所暗示的,您可以将语句拆分为多行以提高可读性,例如:

BEGIN
    EXECUTE IMMEDIATE '
        BEGIN
            FOR V_ROW IN (
                SELECT ROWNUM AS RN,ID AS ID
                FROM (
                    SELECT ID
                    FROM T_OPDM_PLANDEACCION
                    WHERE IDOPORTUNIDAD=2
                    ORDER BY ORDEN
                )
            )
            LOOP
                UPDATE T_OPDM_PLANDEACCION
                SET ORDEN=V_ROW.RN
                WHERE ID=V_ROW.ID;
            END LOOP;
        END;
    ';
END;

对于这个例子,你为什么要这样做并不明显。如果您要使用“参数选择”,那么您可能计划将其注入动态语句中;但即使这样也可能没有必要,具体取决于您的意思以及您获取查询的方式。甚至不清楚为什么要在循环中或使用 PL/SQL 执行此操作。


推荐阅读