2012-01-11 16 views
3

我該怎麼辦,如果我的選擇不帶結果使用SYS_REFCURSOR如何處理無數據發現使用SYS_REFCURSOR - ORACLE

我已經嘗試到目前爲止使用NO_DATA_FOUND,但其沒有工作,我的STATUS回頭率我爲= 1

代碼:

... 
MYVARIABLE IN OUT SYS_REFCURSOR 
... 

OPEN MYVARIABLE FOR 
    SELECT NAME FROM TABLE WHERE COD = 1; 
    STATUS := 1; 
EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
     STATUS := 0; 

任何ideias?

謝謝!


真正的SQL是這樣的:

編輯

V_SQL := 'SELECT SUM(T1.VLRLIQ) VALOR,T1.CODCLI,T1.NOMCLI 
    ,(SELECT METCLI FROM WEB_CRM_CLIVEN T2 
    WHERE T2.CODCLI = T1.CODCLI AND T2.CODVEN = '|| P_CODVEN ||' 
     AND T2.MES = '|| V_MES ||' AND T2.ANO = '|| V_ANO ||') META 
     FROM SAPIENS.USU_VRESNFV T1,SAPIENS.E085CLI T2 
    WHERE T1.CODVEN = '|| P_CODVEN ||' 
    AND TO_CHAR(T1.DATEMI,''YYYY'') = '|| V_ANO ||' 
    AND TO_CHAR(T1.DATEMI,''MM'') = '|| V_MES ||' 
    AND T1.VENFAT = ''S'' 
    '|| V_CGCCPF ||' 
    '|| V_NOMCLI ||' 
    AND T2.CODCLI = T1.CODCLI 
    AND T1.CODEMP = 1 
    GROUP BY T1.CODCLI,T1.NOMCLI 
    UNION 
    SELECT SUM(''0'') VALOR,CODCLI,NOMCLI,(SELECT METCLI FROM WEB_CRM_CLIVEN T3 
     WHERE T3.CODCLI = T2.CODCLI AND T3.CODVEN = '|| P_CODVEN ||' 
     AND T3.MES = '|| V_MES ||' AND T3.ANO = '|| V_ANO ||') META 
     FROM SAPIENS.E085CLI T2 
    WHERE 
    CODCLI IN (SELECT CODCLI FROM WEB_CRM_VEN_CARTEIRA 
     WHERE CODVEN = '|| P_CODVEN ||' AND MES = '|| V_MES ||' AND ANO = '|| V_ANO ||') 
     '|| V_CGCCPF ||' 
     '|| V_NOMCLI ||' 
    GROUP BY CODCLI,NOMCLI 
    ORDER BY VALOR DESC'; 

    STATUS := 1; 

    OPEN RESULTADO FOR V_SQL; 
+0

通常當你使用遊標時,你做的事情很糟糕。你想做什麼?此外,你可以做'如果存在(從表中選擇名稱cod = 1)'來測試是否存在任何行。 – Eric 2012-01-11 18:56:15

+0

@Eric:代碼只是一個例子,將編輯並顯示給你所有 – 2012-01-11 19:04:43

+0

@Eric:檢查更新,這是一個存儲過程,它可以與web服務器php – 2012-01-11 19:06:49

回答

7

在代碼中,你只是打開遊標,但無法從中獲取。當你打開一個遊標時,PL/SQL執行該遊標的查詢。它還標識符合WHERE子句中的條件並加入條件的行。 OPEN實際上不會檢索任何這些行;該操作由FETCH語句執行。然後您將使用遊標屬性來檢查結果集是否爲空;如果是,那麼下面的光標屬性將具有這些值:%實測值= FALSE,%NOTFOUND = TRUE,和%ROWCOUNT = 0

下面是一個例子:

 SQL> DECLARE 
     2  l_cur SYS_REFCURSOR; 
     3  l_col VARCHAR2 (10); 
     4 BEGIN 
     5  OPEN l_cur FOR 
     6  SELECT 'Hi there' col 
     7   FROM DUAL 
     8   WHERE 1 = 0; 
     9 
     10  DBMS_OUTPUT.put_line ('Opened cursor'); 
     11 
     12  FETCH l_cur INTO l_col; 
     13 
     14  DBMS_OUTPUT.put_line ('Fetched from cursor'); 
     15 
     16  IF l_cur%NOTFOUND 
     17  THEN 
     18  DBMS_OUTPUT.put_line ('Oops! No data found. Raising exception...'); 
     19  RAISE NO_DATA_FOUND; 
     20  END IF; 
     21 
     22  CLOSE l_cur; 
     23 EXCEPTION 
     24  WHEN NO_DATA_FOUND 
     25  THEN 
     26  DBMS_OUTPUT.put_line ('Exception raised.'); 
     27 END; 
     28/
    Opened cursor 
    Fetched from cursor 
    Oops! No data found. Raising exception... 
    Exception raised. 

    PL/SQL procedure successfully completed. 
+0

一起工作,稍後返回結果。 – 2012-01-12 10:25:31

2

要稍微修改@埃迪·阿瓦德的回答,我用從遊標變量取通常的代碼模式如下:

DECLARE 
    l_cur SYS_REFCURSOR; 
    l_col VARCHAR2 (10); 
BEGIN 
    OPEN l_cur FOR 
    SELECT 'Hi there' col 
     FROM DUAL 
     WHERE 1 = 0; 

    DBMS_OUTPUT.PUT_LINE('Opened cursor'); 

    <<cursor_loop>> 
    LOOP 
    FETCH l_cur INTO l_col; 

    DBMS_OUTPUT.PUT_LINE('Fetched from cursor'); 

    EXIT cursor_loop WHEN l_cur%NOTFOUND; 

    DBMS_OUTPUT.PUT_LINE('Process data fetched from cursor');  
    END LOOP; -- cursor_loop 

    CLOSE l_cur; 
    DBMS_OUTPUT.PUT_LINE('Closed cursor'); 
END; 

的想法是打開遊標變量(或把它從一個過程後面),然後循環,直到所有的行已從光標中提取。

分享和享受。