存储过程EXECUTE IMMEDIATE V_SQL执行很慢或出不来,如果把V_SQL语句拿出来单独执行很快,这是为啥?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了存储过程EXECUTE IMMEDIATE V_SQL执行很慢或出不来,如果把V_SQL语句拿出来单独执行很快,这是为啥?相关的知识,希望对你有一定的参考价值。
存储过程EXECUTE IMMEDIATE V_SQL执行很慢或出不来,如果把V_SQL语句拿出来单独执行很快,这是为什么?高手帮忙看下,谢谢
参考技术A 这个可能的原因有很多;首先,execute immediate v_sql语句需要硬解析,这是一个较为耗时的过程,而直接拿出来执行的语句,其查询分析树已经存在,所以只需要软解析。
另外,execute immediate语句由于是硬解析,所以每次出来的计划都有可能不同,这是最需要注意的,可以为两种执行方法设置10046跟踪,看一下每种方法的耗时点,以及执行计划的异同。
以下配置可以在plsql developer的命令窗口中执行,也可以在sqlplus中执行;
sql> alter session set events '10046 trace name context forever,level 8';
sql > execute immediate v_sql;
sql> v_sql;
sql> alter session set events '10046 trace name context off';
完成上述操作后登录到数据库服务器上,在cmd(windows)或者 shell(unix)环境下执行
$ tkprof tracefile.trc tracefile.txt sys=no
从存储过程调用时,PL SQL Execute Immediate 不起作用
【中文标题】从存储过程调用时,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 或列规范”
更新,我有不同表的脚本,错误仍然存在。以上是关于存储过程EXECUTE IMMEDIATE V_SQL执行很慢或出不来,如果把V_SQL语句拿出来单独执行很快,这是为啥?的主要内容,如果未能解决你的问题,请参考以下文章
Oracle 的 EXECUTE IMMEDIATE 与存储过程中的 LIKE 子句
从存储过程调用时,PL SQL Execute Immediate 不起作用
PL/SQL里 execute immediate的用法 谁给解释下
存储过程EXECUTE IMMEDIATE V_SQL执行很慢或出不来,如果把V_SQL语句拿出来单独执行很快,这是为啥?