Sql 获取错误绑定变量不存在

Sql 获取错误绑定变量不存在,sql,oracle,Sql,Oracle,当我尝试执行下面的查询时,我得到了所需的输出,但是带有error bind变量的输出不存在。有人能建议修复这个错误吗 错误: Error report - ORA-01006: bind variable does not exist ORA-06512: at line 25 01006. 00000 - "bind variable does not exist" 查询: SET SERVEROUTPUT ON DECLARE v_sql varchar2(5000); v_sql2

当我尝试执行下面的查询时,我得到了所需的输出,但是带有error bind变量的输出不存在。有人能建议修复这个错误吗

错误:

Error report -
ORA-01006: bind variable does not exist
ORA-06512: at line 25
01006. 00000 -  "bind variable does not exist"
查询:

SET SERVEROUTPUT ON

DECLARE

v_sql varchar2(5000);
v_sql2 varchar2(5000);
 v_prj_id varchar2(4000):='B00781728,B00781628,B00781611,A43670001';
v_event  varchar2(5000) := 'CORE_DTS_INTERNAL';

BEGIN

FOR i IN (SELECT trim(regexp_substr(v_prj_id, '[^,]+', 1, LEVEL)) l
         FROM dual 
         CONNECT BY LEVEL <= regexp_count(v_prj_id, ',') + 1 
) LOOP


   v_sql :=  v_sql || 'select '''|| i.l ||''' AS "PRJ_ID", EVENT, email,modified_by,modified from ' || i.l || '.SI_Recipient WHERE EVENT = ''' ||V_EVENT ||'''   UNION ALL ' || chr(10);


END LOOP;

v_sql2 :=  RTRIM(v_sql, 'UNION ALL ' || chr(10) ) ;

 Dbms_Output.Put_Line (v_sql2);

 EXECUTE IMMEDIATE V_SQL2 USING V_EVENT; 



  END;
 /
只需从execute immediate中删除using子句,因为在查询中未使用先前在查询中使用的绑定变量:1:

EXECUTE IMMEDIATE V_SQL2; --USING V_EVENT; 
只需从execute immediate中删除using子句,因为在查询中未使用先前在查询中使用的绑定变量:1:

EXECUTE IMMEDIATE V_SQL2; --USING V_EVENT; 

您可以删除using子句,它将正常工作,但这不是一个好的模式。使用绑定变量是更好的选择,尤其是出于安全原因。您只需更改v_sql的声明,其余代码保持原样

v_sql :=  v_sql || 'select '''|| i.l ||''' AS "PRJ_ID", EVENT, email,modified_by,modified from ' || i.l || '.SI_Recipient WHERE EVENT = :V_EVENT   UNION ALL ' || chr(10);
编辑:
正如有人在对另一个答案的评论中所说的那样,我的解决方案当然只能在没有循环或一次性循环的情况下工作。硬解析总是一个坏主意,但如果不写一些糟糕的代码,就不能用其他方式完成。我的解决方案不起作用,因为在执行即时sql代码时,无论绑定的名称如何,都需要为每个绑定传递值。

您可以删除using子句,它会起作用,但这不是一个好的模式。使用绑定变量是更好的选择,尤其是出于安全原因。您只需更改v_sql的声明,其余代码保持原样

v_sql :=  v_sql || 'select '''|| i.l ||''' AS "PRJ_ID", EVENT, email,modified_by,modified from ' || i.l || '.SI_Recipient WHERE EVENT = :V_EVENT   UNION ALL ' || chr(10);
编辑: 正如有人在对另一个答案的评论中所说的那样,我的解决方案当然只能在没有循环或一次性循环的情况下工作。硬解析总是一个坏主意,但如果不写一些糟糕的代码,就不能用其他方式完成。我的解决方案不起作用,因为在执行即时sql代码时,无论绑定的名称如何,都需要为每个绑定传递值。

更改

v_sql :=  v_sql ... WHERE EVENT = ''' ||V_EVENT ||'''   UNION ALL ...

绑定变量以冒号前缀出现在SQL查询中,如:v_event

以这种方式使用绑定变量比仅从executeimmediate中删除使用V_事件要好。使用绑定变量的SQL语句更具可扩展性,所需的锁存和内存更少。

更改

v_sql :=  v_sql ... WHERE EVENT = ''' ||V_EVENT ||'''   UNION ALL ...

绑定变量以冒号前缀出现在SQL查询中,如:v_event


以这种方式使用绑定变量比仅从executeimmediate中删除使用V_事件要好。使用bind变量的SQL语句具有更高的可伸缩性,所需的锁存和内存更少。

using子句中需要多少变量?你看到它在循环中了吗?没有,我没注意到。这是一个糟糕的模式-每个项目一个模式。在特定时间为每组感兴趣的项目构建动态查询是不可伸缩的。根据进程运行的频率,对每个调用进行单独的查询将导致库缓存溢出,并导致过度的硬解析。如果我有时间或者你可以,我可以用更好的模式更新我的答案。同时,您是对的:没有方便的方法将绑定变量与构建在循环中的查询一起使用?你看到它在循环中了吗?没有,我没注意到。这是一个糟糕的模式-每个项目一个模式。在特定时间为每组感兴趣的项目构建动态查询是不可伸缩的。根据进程运行的频率,对每个调用进行单独的查询将导致库缓存溢出,并导致过度的硬解析。如果我有时间或者你可以,我可以用更好的模式更新我的答案。同时,你是对的:没有方便的方法将绑定变量与构建在循环中的查询一起使用。你正在使用循环,根据我回答的上一个问题,使用子句将需要4倍相同的变量。你正在使用循环,根据我回答的上一个问题,使用子句将需要4倍相同的变量。