2011-02-01 12 views
6

Oracle'da varchar2 paramater kullanan bir Prosedürüm var. Bu parametrenin değerine dayanarak, bir imleci tanımlamam gerekiyor. İmleç, parametrenin değerine bağlı olarak farklı tablolarda çalışır.Koşullu bir İmleç tanımlayın

Aşağıdakine benzer bir şey yapmak istedim ama CURSOR tanımlama kodunda bir hata attı. Herhangi bir fikir?

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; 

cevap

8

örneğin, bir REF CURSOR ihtiyaç ve conditionaly açacağım:

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 ... o BOMBA olduğunu !!! Harika çalışıyor .... teşekkür ederim – MikeTWebb

2

isterim muhtemelen (iki döngüler aynı işlevleri çağırabilir) böyle kod şey

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; 

Ayrıca imleci açmak için dinamik SQL kullanabilirsiniz ama bu daha karmaşık bir eğilimi, Özellikle sadece iki seçenek varsa.

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

Hatta döngü için örtülü iç koşulunu kullanabilirsiniz. İmleç beyannamesi veya SYS_REFCURSOR (Özür onları sevmediğim) olmadan - Sana örtülü imleç beyanı Burada içeride, v_action, senin değişkenleri kullanabilirsiniz demek:

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;