2011-05-05 36 views
15

我有一個循環內執行的提取。如果此提取失敗(無數據),我想CONTINUE循環到EXCEPTION內的下一條記錄。是否有可能從異常繼續循環?

這可能嗎?

我得到一個ORA-06550 & PLS-00201 identifer CONTINUE must be declared

DECLARE 
    v_attr char(88); 
CURSOR SELECT_USERS IS 
SELECT id FROM USER_TABLE 
WHERE USERTYPE = 'X'; 
BEGIN 
    FOR user_rec IN SELECT_USERS LOOP  
     BEGIN 
      SELECT attr INTO v_attr 
      FROM ATTRIBUTE_TABLE 
      WHERE user_id = user_rec.id;    
     EXCEPTION 
      WHEN NO_DATA_FOUND THEN 
       -- user does not have attribute, continue loop to next record. 
       CONTINUE; 
     END;   
    END LOOP; 
END; 
+1

「CONTINUE」語句是11g中的一項新功能。你確定你正在運行該版本? – angus 2011-05-05 20:08:33

+0

順便說一句,在這裏看到:http://stackoverflow.com/questions/177752/continue-keyword-in-oracle-10g-pl-sql – angus 2011-05-05 20:09:29

+1

@angus - 我們是在10g中,長號。猜猜我只是使用'NULL;'和一堆條件IF語句來幫助循環。將您的答案發布爲答覆,並將其標記爲正確答案。 – ProfessionalAmateur 2011-05-05 20:16:02

回答

9

在您所提供的結構,你不需要繼續。處理異常後,執行END後的語句,假定您的EXCEPTION塊不會終止該過程。換句話說,它將繼續進行user_rec循環的下一次迭代。

你還需要選擇到一個變量的BEGIN塊中:

SELECT attr INTO v_attr FROM attribute_table... 

顯然,你必須聲明v_attr以及...

+0

謝謝,我做了一個快速和骯髒的例子,你是正確的選擇一個變量。 – ProfessionalAmateur 2011-05-05 20:27:36

+0

@ProAm:我認爲可能是這樣,但以防萬一...... – DCookie 2011-05-05 20:29:44

5

如何在OLE goto語句(我知道,我知道,但它工作得很好這裏;)

DECLARE 
    v_attr char(88); 
CURSOR SELECT_USERS IS 
SELECT id FROM USER_TABLE 
WHERE USERTYPE = 'X'; 
BEGIN 
    FOR user_rec IN SELECT_USERS LOOP  
     BEGIN 
      SELECT attr INTO v_attr 
      FROM ATTRIBUTE_TABLE 
      WHERE user_id = user_rec.id;    
     EXCEPTION 
      WHEN NO_DATA_FOUND THEN 
       -- user does not have attribute, continue loop to next record. 
       goto end_loop; 
     END; 

     <<end_loop>> 
     null;   
    END LOOP; 
END; 

只要把end_loop在最末端當然循環。 null可以用一個提交或者一個計數器增量代替,直到你。

0

在這個例子中,你真的應該只使用一個外連接。

declare 
begin 
    FOR attr_rec IN ( 
    select attr 
    from USER_TABLE u 
    left outer join attribute_table a 
    on (u.USERTYPE = 'X' and a.user_id = u.id) 
) LOOP 
    <process records> 
    <if primary key of attribute_table is null 
    then the attribute does not exist for this user.> 
    END LOOP; 
END; 
0

通知您可以使用WHEN exception THEN NULL相同的方式,你會使用WHEN exception THEN continue。示例:

DECLARE 
     extension_already_exists EXCEPTION; 
     PRAGMA EXCEPTION_INIT(extension_already_exists, -20007); 
     l_hidden_col_name varchar2(32); 
    BEGIN 
     FOR t IN ( SELECT table_name, cast(extension as varchar2(200)) ext 
        FROM all_stat_extensions 
        WHERE owner='{{ prev_schema }}' 
         and droppable='YES' 
        ORDER BY 1 
       ) 
     LOOP 
      BEGIN 
       l_hidden_col_name := dbms_stats.create_extended_stats('{{ schema }}', t.table_name, t.ext); 
      EXCEPTION 
       WHEN extension_already_exists THEN NULL; -- ignore exception and go to next loop iteration 
      END; 
     END LOOP; 
    END;