oracle - 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。
解决方案
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;
也就是说,在您拥有的内容周围添加了BEGIN
and (以及缺少的分号)。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 执行此操作。
推荐阅读
- vb.net - 使用内存流读取 Byte()-Array 中的图像时出现 6 个奇怪的零值
- node.js - 如何与 Node.js 中的本地模块共享依赖项?
- laravel - 使用集合 diff 函数时如何修复“stdClass 类的对象无法转换为字符串”
- r - 使用 Sjplot 绘图时,数据点的形状可以根据组进行更改吗?
- flutter - Flutter:如何在 Flutter 中设置下拉菜单的高度
- javascript - 必须按两次提交才能调用 firebase 功能
- mysql - 创建一个简单的 dot net core 和 mysql docker 容器组合
- javascript - 通过 Javascript 让 Wowhead 工具提示在 Excel 电子表格中发挥作用
- javascript - 在 IE 11 中渲染反应应用程序给了我“你需要启用 javascript 来运行这个应用程序”
- python - pymc 先验的可视化