1

そのため、 LISTAGG()関数を使用して、基になるクエリ内で使用するカンマ区切りのリストを作成しようとしています。リストの生成は正常に機能し、デバッグ目的で出力を適用したところ、リストを本来あるべき姿で表示できます。

値: 'AB'、'AZ'、'BC'、'CA'、'CT'、'DC'、'FL'、'FO'、'GA'、'IL'、'KS'、'MA'、 'MB','ME','MN','MS','MT','NB','NC','NL','NOVA SCOTIA','NS','NT','NU',' NY'、'ON'、'ONTARIO'、'OR'、'PE'、'QC'、'ケベック'、'ケベック'、'サスカチュワン'、'SK'、'TX'、'VT'、'WA' ,'YT'

このリスト変数をクエリに渡そうとすると、何かが返されるかどうかを確認するためだけに、何も返されませんが、「v_Province」を使用する代わりに、上から州/州リストをコピー/ペーストすると (そのまま) where句、結果が返されます。私は何を間違っていますか?

  DECLARE
     v_PROVINCE varchar2(500);
     v_results varchar2(1000);
  BEGIn
        dbms_output.enable(1000000);  

       Select '''' || LISTAGG(STATE, ''',''') WITHIN GROUP (ORDER BY STATE) || '''' PROV 
       INTO v_PROVINCE
       from (Select distinct STATE from ADDRDATA where STATE IS NOT NULL);

   DBMS_OUTPUT.PUT_LINE('VALUES: ' || v_PROVINCE);

   Select CITY
   INTO v_results
   from VWPERSONPRIMARYADDRESS
   where state in (v_Province)
   AND ROWNUM <= 1;

   DBMS_OUTPUT.PUT_LINE(v_results);


  END;
  /
4

2 に答える 2

2

まず、可能であれば、すべてを 1 つのステートメントで実行する方が効率的です。

すべてを単一の文字列に返すため、2 番目のクエリは機能しません。これは、IN ステートメントで必要なコンマ区切りのリストではありません。

ただし、これを回避するにはちょっとしたコツがあります。2 つの SELECT ステートメントの間の何かに文字列を使用していると仮定すると、文字regexp_substr()列を使用可能なものに変えるためにいじることができます。

このようなものが機能します。

select city
  from vwpersonprimaryaddress
 where state in ( 
           select regexp_substr(v_province,'[^'',]+', 1, level) 
             from dual
          connect by regexp_substr(v_province, '[^'',]+', 1, level) is not null
                  )

v_provinceたとえば、これを機能させるには、変数を 2 回引用符で囲むように変更する必要があります'''AB'',''AZ'',''BC'''

これが実際の例です

于 2012-11-06T21:38:54.527 に答える
1

IN演算子はコンマ区切りのリストを単一の値として扱うため、あなたがしようとしていることはうまくいきません。理論的には、値を 1 つの文字列に集めてから、その文字列を個々の値に解析して、次のクエリで解釈できるようにすることができます。しかし、それは本当に悪い考えです。

配列を使用して、最初のクエリから 2 番目のクエリに値のリストを渡すことをお勧めします。

create type nt_varchar_50 as table of varchar2(10)
/

DECLARE
     v_PROVINCE nt_varchar_50;
     v_results varchar2(1000);
     cursor cur_provinces is
        Select distinct STATE from ADDRDATA where STATE IS NOT NULL;
     i pls_integer;
BEGIN
     dbms_output.enable(1000000); 
     open cur_provinces;
     fetch cur_provinces bulk collect into v_PROVINCE;
     close cur_provinces;

     DBMS_OUTPUT.PUT('VALUES: ');
     for i in v_PROVINCE.first .. v_province.last loop
         if i <> 1 then
            DBMS_OUTPUT.PUT(', ');
         end if;              
         DBMS_OUTPUT.PUT(v_PROVINCE(i));
     end loop;
     DBMS_OUTPUT.PUT_LINE();

     Select CITY
     INTO v_results
     from VWPERSONPRIMARYADDRESS
     where state in (select * from table(v_Province))
     AND ROWNUM <= 1;

     DBMS_OUTPUT.PUT_LINE(v_results);
END;
  /

もちろん、これでも最初から単一の SQL ステートメントを使用する場合よりも効率が大幅に低下します。実際には、この種の手法は、2 つのクエリ間で SQL に適していない何らかの処理を行う必要がある場合、または最初の結果セットを複数回使用する必要がある場合にのみ使用してください。

于 2012-11-06T20:51:25.223 に答える