从存储过程调用时,PL SQL Execute Immediate 不起作用

Posted

技术标签:

【中文标题】从存储过程调用时,PL SQL Execute Immediate 不起作用【英文标题】:PL SQL Execute Immediate not working when calling it from a stored procedure 【发布时间】:2020-07-15 20:12:48 【问题描述】:

我已经创建了以下 SP

create or replace PROCEDURE RM_SUPPORT_SCRIPTS_V2 
(
              V_TABLENAME IN USER_TABLES.table_name%type
            , V_SETCOLNAME IN NVARCHAR2 
            , V_SETVALUE IN NVARCHAR2 
            , V_WHERECOLNAME IN NVARCHAR2 
            , V_WHEREKEYVALUE IN NVARCHAR2 
            , USER_ID IN NVARCHAR2 
    ) 
    IS 
    BEGIN
      EXECUTE IMMEDIATE 
        'UPDATE '||DBMS_ASSERT.simple_sql_name(V_TABLENAME) 
            ||' SET :1 = :2, update_by_userid = :3, UPDATE_DATE = SYSDATE'
            ||' WHERE :4 = :5 '
            using V_SETCOLNAME, V_SETVALUE, USER_ID, V_WHERECOLNAME, V_WHEREKEYVALUE; 
    
END RM_SUPPORT_SCRIPTS_V2;

但是当我从 EXECUTE 语句中调用它时

EXEC RM_SUPPORT_SCRIPTS_V2 (USERS_TABLE, USER_ID,ORTEGALUX,USER_ID,TESTED,FX);    

我收到以下错误

错误报告 - ORA-06550:第 1 行,第 31 列: PLS-00357:此上下文中不允许表、视图或序列引用“USERS_TABLE” ORA-06550:第 1 行,第 7 列: PL/SQL:语句被忽略 06550. 00000 - “第 %s 行,第 %s 列:\n%s” *原因:通常是 PL/SQL 编译错误。 *行动:

有谁知道为什么会发生这种情况?我尝试在每个表、列的调用中加入简单的逗号,但仍然失败。

谢谢。

【问题讨论】:

【参考方案1】:

错误来自调用,而不是过程。您正在传递字符串,因此您需要引用它们:

EXEC RM_SUPPORT_SCRIPTS_V2 ('USERS_TABLE', 'USER_ID','ORTEGALUX','USER_ID','TESTED','FX');

但是你不能对列名使用绑定变量,你需要将它们连接起来,就像你使用表名一样。

      EXECUTE IMMEDIATE 
        'UPDATE '||DBMS_ASSERT.simple_sql_name(V_TABLENAME) 
            ||' SET ' || V_SETCOLNAME || ' = :1, update_by_userid = :2, UPDATE_DATE = SYSDATE'
            ||' WHERE ' || V_WHERECOLNAME || ' = :3 '
            using V_SETVALUE, USER_ID, V_WHEREKEYVALUE; 

尽管您可能也想为这些添加断言检查。

【讨论】:

谢谢@Alex Poole 我已尝试按照您的通知引用,但我现在收到此错误code 错误从第 1 行开始:命令中的 BEGIN RM_SUPPORT_SCRIPTS_V2 ('user_list', 'USERS_TABLE' ,'ORTEGALUX','USER_ID','TESTED','FX');结尾;错误报告 - ORA-06550:第 1 行,第 316 列:PLS-00201:必须声明标识符 'RM_SUPPORT_SCRIPTS_V2' ORA-06550:第 1 行,第 316 列:PL/SQL:语句被忽略 06550。00000 -“第 %s 行,列%s:\n%s" *原因:通常是 PL/SQL 编译错误。 *行动: 您将 RM 更改为 FMV?那似乎不存在...? 嗯,它真的存在吗?在您调用它的同一架构中? (错误真的是指第 316 列吗?这看起来很奇怪。 你是对的,我的架构有误,现在我得到了这个 ORA-01747: invalid user.table.column, table.column, or column specification ORA-06512: at "OPTIMA.RM_SUPPORT_SCRIPTS_V2" ,第 12 行 ORA-06512:在第 1 行 01747.00000 -“无效的 user.table.column、table.column 或列规范” 更新,我有不同表的脚本,错误仍然存​​在。

以上是关于从存储过程调用时,PL SQL Execute Immediate 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 存储函数和过程

Oracle 存储过程

如何使用EXECUTE关键字执行带参数的PL / SQL存储过程[关闭]

Oracle 存储过程

从存储过程中调用 PL/SQL 游标得到结果

从 shell 脚本调用 PL/SQL 存储过程并捕获 out 参数