2

カーソル宣言で変数を代入することは可能かどうかお尋ねしたいと思います。

CURSOR cur_name IS <variable_name>

私が達成したいのは、カーソルでは、select ステートメントの where 句と from 句の一部が、別の select の結果によって異なることです。以下のように:

select count(*) from table_name
v_cnt
where cond1;

v_cnt が 0 の場合、カーソルは次のようになります。

 cursor cur_name IS 
    select * from tab_name1
    where cond1;

v_cnt > 0 の場合、カーソルは次のようになります。

    cursor cur_name IS 
    select * from tab_name2
    where cond1
    and cond2;

if-else を実行してから、カーソルに割り当てられる選択を連結できるかどうか疑問に思っていました。

    cursor cur_name IS 
    select * from tab_name
    if v_cnt > 0
    where cond2;
    else 
    where cond1;

詳細が必要な場合はお知らせください。フィードバックをお待ちしております。

4

4 に答える 4

2

これを行うには多くの方法があり、多くのトレードオフが関係しています。

アレクサンダー・トカレフの答えは最も柔軟です。ただし、動的 ​​SQL は扱いにくい場合があり、依存関係の問題がコンパイル時に表示されないなどがあります。Balaji Sukumaran の答えは柔軟性に欠けますが、より単純であり、コードを小さなチャンクに分割します。

選択された列が常に同じである場合は、次のような方法を使用できます。

cursor cur_name(v_cnt number) is
select *
from tab_name1
where 1=1 /*condition 1*/
    and v_cnt > 0
---------
union all
---------
select *
from tab_name2
where 2=2 /*condition 2*/
    and (v_cnt is null or v_cnt <= 0);

それはすべてをまとめたもので、バラジの答えよりも混乱する可能性があります. ただし、すべてのロジックを 1 つの SQL にまとめた方がよい場合もあります。ロジックの繰り返しを減らすのに役立つ場合があります。

(また、Oracle が実際に両方のクエリを使用し、実行速度が遅いことを心配する必要はありません。どのクエリが使用されるかを制御するバインド変数があることを知っているのは賢明です。それがFILTER説明計画のステップで行われていることです。)

于 2012-09-12T06:41:42.417 に答える
1

このようなものをお探しですか?

DECLARE
  V_CNT VARCHAR2(20);

  CURSOR C1
  IS
  SELECT * from Tab1;

  CURSOR C2
  IS
  SELECT * from Tab2;   

BEGIN
  SELECT COUNT(*) INTO V_CNT FROM Table_Name;
    IF V_CNT > 0 THEN
       OPEN C1;
         --code
        Close C1;
    ELSE
       OPEN C2;
          --code
       CLOSE C2;
    END IF;
 END;
于 2012-09-12T05:18:47.743 に答える
1

カーソルが非常に動的である場合は、次のようなものを使用します。

 declare
  c sys_refcursor;
  <here declare the record you would like fetch results to> 
 begin
  open c for 'you query in quotes as the string that you created before regarding your     conditions';
  loop
   FETCH c INTO your record;
   EXIT WHEN c%NOTFOUND;
  end loop;
 end;

いずれの場合も、http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/sqloperations.htm#BABFEJEDを調べてください。それは私の意見によってあなたのケースを説明しています。

于 2012-09-12T06:01:42.433 に答える
1

次のようなものを使用しないのはなぜですか

select  * 
from    tab_name 
WHERE   (v_cnt = 0  AND cond1)
OR      (v_cnt > 0  AND cond2)
于 2012-09-12T04:01:36.170 に答える