簡體   English   中英

有條件地定義一個Cursor

[英]Conditionally define a Cursor

我在Oracle中有一個帶有varchar2參數的過程。 根據該參數的值,我需要定義一個游標。 光標將根據參數的值在不同的表上運行。

我想做類似下面的事情,但它在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;

你將需要一個REF CURSOR並打開它,例如:

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

我可能會編寫類似這樣的東西(兩個循環可能調用相同的函數)

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打開游標,但這往往會變得更復雜,特別是如果只有兩個選項。

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;
  ...

您甚至可以在隱式for循環中使用條件。 沒有游標聲明或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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM