2011-02-01 7 views
6

私は、varchar2パラメーターを取るOracleのプロシージャーを持っています。そのパラメータの値に基づいて、カーソルを定義する必要があります。カーソルは、パラメータの値に基づいて異なるテーブル上で動作します。条件付きでカーソルを定義する

私は以下のようにしたいと思っていましたが、CURSOR定義コードにエラーがスローされます。何か案は?私はおそらくこのような何かをコーディングし

PROCEDURE GET_RECORDS(v_action IN VARCHAR2) 
IS 
CURSOR get_records 
IS 
     IF(v_action = 'DO THIS') THEN 
      SELECT * from <THIS>; 
     ELSE 
      SELECT * from <THAT>; 
     END IF; 
BEGIN 
     OPEN get_records; 

     FETCH get_records 
     INTO v_thing; 

     v_loop := 0; 
     WHILE get_records%FOUND 
     LOOP 

      FETCH get_records 
      INTO v_thing; 

     END LOOP; 
     CLOSE get_records; 
END; 

答えて

8

あなたはREF CURSORを必要とし、例えば、conditionalyそれを開きます:

SQL> CREATE OR REPLACE PROCEDURE GET_RECORDS(v_action IN VARCHAR2) IS 
    2  v_thing  VARCHAR2(10); 
    3  get_records SYS_REFCURSOR; 
    4 BEGIN 
    5  IF (v_action = 'DO THIS') THEN 
    6  OPEN get_records FOR 
    7   SELECT 1 FROM dual; 
    8  ELSE 
    9  OPEN get_records FOR 
10   SELECT 2 FROM dual; 
11  END IF; 
12 
13  LOOP 
14  FETCH get_records INTO v_thing; 
15  EXIT WHEN get_records%NOTFOUND; 
16  /* do things */ 
17  dbms_output.put_line(v_thing); 
18  END LOOP; 
19  CLOSE get_records; 
20 END; 
21/

Procedure created 

SQL> exec get_records ('DO THIS'); 
1 

PL/SQL procedure successfully completed 

SQL> exec get_records ('DO THAT'); 
2 

PL/SQL procedure successfully completed 
+0

@Vincent ...それはBOMBです!素晴らしい作品です...ありがとう – MikeTWebb

2

(2つのループが同じ機能を呼び出すことができます)

BEGIN 
    IF(v_action = 'DO THIS') 
    THEN 
    FOR this_cur IN (SELECT * FROM <THIS>) 
    LOOP 
     <<do something>> 
    END LOOP; 
    ELSE 
    FOR that_cur IN (SELECT * FROM <THAT>) 
    LOOP 
     <<do something else>> 
    END LOOP; 
    END IF; 
END; 

、あなたはまた、カーソルを開くために、動的SQLを使用することができますが、それはより複雑になる傾向にあります特にオプションが2つしかない場合は特にそうです。

IS 
    get_records SYS_REFCURSOR; 
    l_sql_stmt VARCHAR2(100); 
BEGIN 
    IF(v_action = 'DO THIS') 
    THEN 
    l_sql_stmt := 'SELECT * from <THIS>'; 
    ELSE 
    l_sql_stmt := 'SELECT * from <THAT>'; 
    END IF; 

    OPEN get_records FOR l_sql_stmt; 
    ... 
1

あなたも、ループの暗黙の内の条件を使用することができます。カーソル宣言またはSYS_REFCURSOR(私は彼らは申し訳ありませんが嫌い)がなければ - 私はあなたの変数を使用できることを意味し、ここでv_action、暗黙カーソル宣言内:

BEGIN 
    FOR this_cur IN (
     SELECT * FROM <THIS> 
     WHERE v_action = 'DO THIS' 
    ) LOOP 
     <<do something>> 
    END LOOP; 
    FOR that_cur IN (
     SELECT * FROM <THIS> 
     WHERE v_action <> 'DO THIS' 
    ) LOOP 
     <<do something else>> 
    END LOOP; 
    END IF; 
END; 
関連する問題