2011-02-01 45 views
6

Tôi có một thủ tục trong Oracle có một tham số varchar2. Dựa trên giá trị của tham số đó, tôi cần xác định con trỏ. Con trỏ sẽ hoạt động trên các bảng khác nhau dựa trên giá trị của tham số.Điều kiện xác định một con trỏ

Tôi muốn làm điều gì đó như dưới đây nhưng nó sẽ phát ra lỗi trong đoạn mã định nghĩa CURSOR. Bất kỳ ý tưởng?

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; 

Trả lời

8

bạn sẽ cần một REF CURSOR và mở nó conditionaly, ví dụ:

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 ... đó là BOMB !!! Công trình tuyệt vời .... Cảm ơn bạn – MikeTWebb

2

tôi sẽ có lẽ cái gì đó mã như thế này (nơi hai vòng có thể gọi các chức năng tương tự)

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; 

Bạn cũng có thể sử dụng SQL động để mở con trỏ nhưng có xu hướng trở nên phức tạp hơn, đặc biệt nếu chỉ có hai lựa chọn.

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

Bạn thậm chí có thể sử dụng điều kiện bên trong tiềm ẩn cho vòng lặp. Mà không khai báo con trỏ hoặc SYS_REFCURSOR (Tôi không thích họ xin lỗi) - Tôi có nghĩa là bạn có thể sử dụng các biến của bạn, đây v_action, bên trong khai báo con trỏ ngầm:

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; 
Các vấn đề liên quan