在for循环中调用存储过程

bla*_*ath 4 oracle plsql

我在 SQL Developer 中创建并存储了一个过程。我可以调用它并且它按预期工作。

但是,如果我尝试在一组表的 for 循环中使用它,则会出现错误:

ORA-06512:在第 10 行

  1. 00000 - “无效的 SQL 语句”

这是程序:

create or replace PROCEDURE ADD_PARAMETERS 
(
  TBL_NAME IN VARCHAR2 
) AS 
BEGIN
  
  EXECUTE IMMEDIATE 'ALTER TABLE '||TBL_NAME||' ADD(FB_AREA_HA Float)';
  
  EXECUTE IMMEDIATE 'UPDATE '||TBL_NAME||' SET FB_AREA_HA = FB_AREA/10000';
END ADD_PARAMETERS;
Run Code Online (Sandbox Code Playgroud)

这里是带有程序的 for 循环:

SET SERVEROUT ON
DECLARE

sql_stmnt VARCHAR2(400);

BEGIN
    FOR x in (SELECT * FROM all_tables WHERE table_name LIKE 'BBX_%')
    LOOP
        sql_stmnt := 'EXECUTE ADD_PARAMETERS('''||x.TABLE_NAME||''')';
        DBMS_OUTPUT.PUT_LINE(sql_stmnt||';');
        EXECUTE IMMEDIATE sql_stmnt;
    END LOOP;
END;
Run Code Online (Sandbox Code Playgroud)

这个错误的原因是什么?我很确定它不是第 10 行。

Ale*_*ole 8

EXECUTE不是 SQL 命令。它是匿名块的 SQL*Plus(和其他)客户端简写。动态语句在 SQL 上下文中执行,而不是在客户端中执行,因此无法识别 - 因此出现错误(它确实来自块的第 10 行,因为这就是EXECUTE IMMEDIATE发生的地方)。

你可以做相当于扩展该速记:

sql_stmnt := 'BEGIN ADD_PARAMETERS('''||x.TABLE_NAME||'''); END;';
Run Code Online (Sandbox Code Playgroud)

但是您不需要过程调用的动态 SQL ,您可以这样做:

BEGIN
    FOR x in (SELECT * FROM all_tables WHERE table_name LIKE 'BBX_%')
    LOOP
        ADD_PARAMETERS(x.TABLE_NAME);
    END LOOP;
END;
/
Run Code Online (Sandbox Code Playgroud)