ORACLE 立即执行循环 ORA-06512
ORACLE EXECUTE IMMEDIATE FOR LOOP 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 中的字符串与第二行完全相同。
我需要为参数 SELECT 执行 FOR 循环。
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
和 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;
在这个例子中,您为什么要这样做并不明显。如果您打算使用 'parametric select' 那么您可能打算将其注入到动态语句中;但即使那样也可能不是必需的,具体取决于您的意思以及您如何获得查询。甚至不清楚为什么要在循环中或使用 PL/SQL 执行此操作。
我正在尝试执行整个 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 中的字符串与第二行完全相同。
我需要为参数 SELECT 执行 FOR 循环。
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
和 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;
在这个例子中,您为什么要这样做并不明显。如果您打算使用 'parametric select' 那么您可能打算将其注入到动态语句中;但即使那样也可能不是必需的,具体取决于您的意思以及您如何获得查询。甚至不清楚为什么要在循环中或使用 PL/SQL 执行此操作。