不替换IN子句

时间:2015-12-29 09:43:29

标签: oracle plsql oracle11g

当我运行此查询时,我没有得到输出。但是当我将值硬编码到所有3个变量时,我得到了光标所需的结果。如何让它运行上面的查询?

PROCEDURE P_getdata(zip            IN LONG,
                    streetnumberda IN LONG,
                    apt_n          IN LONG,
                    cur            OUT C_DATA)
AS
  l_query LONG;
BEGIN
    l_query :=
'select firstname, lastname, streetname, city from mytable 
                       where zip IN(SELECT REGEXP_SUBSTR(:zip,''[^,]+'', 1, LEVEL) FROM DUALCONNECT BY REGEXP_SUBSTR(:zip, ''[^,]+'', 1, LEVEL) IS NOT NULL) 
                       AND streetnumber IN(SELECT REGEXP_SUBSTR(:streetnumberda,''[^,]+'', 1, LEVEL) FROM DUAL CONNECT BY REGEXP_SUBSTR(:streetnumberda, ''[^,]+'', 1, LEVEL) IS NOT NULL) 
                       AND apt_num in(SELECT REGEXP_SUBSTR(:apt_n,''[^,]+'', 1, LEVEL) FROM DUALCONNECT BY REGEXP_SUBSTR(:apt_n, ''[^,]+'', 1, LEVEL) IS NOT NULL)'
;

OPEN cur FOR l_query;
END; 

参数值是(都是varchar)

           a ='202020';
           b='12','13','10','92','02','02'
           c='A','B'

2 个答案:

答案 0 :(得分:2)

您必须为查询中的所有占位符提供参数 占位符是以:字符开头的参数,例如::zip:apt_n
有关使用占位符(有示例)的更多信息,您可以找到它 http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/dynamic.htm#BHCGEFCA

您问题中的查询有6个占位符:

  

从mytable中选择名字,姓氏,街道名称,城市   其中zip IN(SELECT REGEXP_SUBSTR(:zip ,&#39;&#39; [^,] +&#39;&#39;,1,LEVEL)来自DUALCONNECT BY REGEXP_SUBSTR(:zip ,&#39;&#39; [^,] +&#39;&#39;,1,LEVEL)IS NOT NULL)                          AND streetnumber IN(SELECT REGEXP_SUBSTR(:streetnumberda ,&#39;&#39; [^,] +&#39;&#39;,1,LEVEL)FROM DUAL CONNECT BY REGEXP_SUBSTR(< strong>:streetnumberda ,&#39; [^,] +&#39;&#39;,1,LEVEL)IS NOT NULL)                          AND apt_num in(SELECT REGEXP_SUBSTR(:apt_n ,&#39;&#39; [^,] +&#39;&#39;,1,LEVEL)FROM DUALCONNECT BY REGEXP_SUBSTR(:apt_n ,&#39;&#39; [^,] +&#39;&#39;,1,LEVEL)不是空的)&#39;   ;

因此,您必须在USING关键字后提供6个绑定参数:

OPEN cur FOR l_query USING zip, zip, streetnumberda, streetnumberda, apt_n, apt_n;

我已经测试了您的代码并且它有效,下面是我的代码段 可能是您的代码中存在问题:FROM DUALCONNECT BY - DUAL和CONNECT BY之间缺少空格。

CREATE TABLE mytable(
  firstname varchar2(100), lastname varchar2(100), streetname varchar2(100), city varchar2(100),
  zip varchar2(100), streetnumber varchar2(100), apt_num  varchar2(100))
;

insert into mytable values('FNAME','LNAME','STREET','CITY','202020','12','A' );

CREATE OR REPLACE PROCEDURE P_getdata(zip  IN LONG,
                    streetnumberda IN LONG,
                    apt_n          IN LONG,
                    cur            OUT sys_refcursor)
AS
  l_query LONG;
BEGIN
    l_query :=
    q'[select firstname, lastname, streetname, city from mytable 
     where zip IN(SELECT REGEXP_SUBSTR(:zip,'[^,]+', 1, LEVEL) FROM DUAL
                  CONNECT BY REGEXP_SUBSTR(:zip, '[^,]+', 1, LEVEL) IS NOT NULL) 
       AND streetnumber IN(SELECT REGEXP_SUBSTR(:streetnumberda,'[^,]+', 1, LEVEL) FROM DUAL 
                           CONNECT BY REGEXP_SUBSTR(:streetnumberda, '[^,]+', 1, LEVEL) IS NOT NULL) 
       AND apt_num in(SELECT REGEXP_SUBSTR(:apt_n,'[^,]+', 1, LEVEL) FROM DUAL
                      CONNECT BY REGEXP_SUBSTR(:apt_n, '[^,]+', 1, LEVEL) IS NOT NULL)]';
  DBMS_OUTPUT.PUT_LINE( l_query );
  OPEN cur FOR l_query USING zip, zip, streetnumberda, streetnumberda, apt_n, apt_n;
END; 
/

DECLARE
   cur sys_refcursor;
   fname varchar2(100); lname varchar2(100); strname varchar2(100); city varchar2(100);
BEGIN
  P_getdata('202020','12,13,10,92,02,02', 'A,B', cur );
  LOOP
     FETCH cur INTO fname, lname, strname, city;
     EXIT WHEN cur%NOTFOUND;
     DBMS_OUTPUT.PUT_LINE( fname||'--'||lname||'--'||strname||'--'||city );
  END LOOP;
END;
/

答案 1 :(得分:1)

打开cur选择firstname,lastname,streetname,city            来自mytable            zip(SELECT REGEXP_SUBSTR(A,'[^,] +',1,LEVEL)   来自双重     通过REGEXP_SUBSTR连接(A,'[^,] +',1,LEVEL)IS NOT NULL    AND streetnumber IN(SELECT REGEXP_SUBSTR(B,'[^,] +',1,LEVEL)   来自双重     通过REGEXP_SUBSTR连接(B,'[^,] +',1,LEVEL)IS NOT NULL    AND apt_num in(SELECT REGEXP_SUBSTR(C,'[^,] +',1,LEVEL)   来自双重     CONNEX BY REGEXP_SUBSTR(C,'[^,] +',1,LEVEL)是非空的

它正在运作