2016-08-20 137 views
2

在Oracle 12.1中,我有一個相當簡單的PL/SQL例程。輸出是單個值,可以是逗號分隔的名稱列表或字符串「NO_DATA」。沒有其他輸出允許。對於輸入,有一個單一的值,一個公司名稱。如果我硬編碼公司名稱,並從SQL窗口運行SQL語句(不是函數),它運行良好,所以我知道SQL是有效的。這個問題與異常處理有關。如果我沒有任何異常處理,並傳遞一個有效的名稱給函數,它會給我一個有效的輸出。當我找不到數據時,我需要能夠處理這種情況,所以我添加了簡單的異常處理。這是我得到我的問題的地方。有了異常處理代碼,如果我傳入了一個不合適的值(又名公司名稱,未找到),我就會像'我應該'那樣得到'NO_DATA'。如果我傳遞了一個很好的值,那麼我得到一個PL/SQL錯誤ORA-06503:PL/SQL:函數返回時沒有值。這是我的代碼。PL/SQL異常處理 - 函數無返回值返回

create or replace FUNCTION authorized_email(nn1 in varchar2) 
    RETURN varchar2 
    IS 
    thisName varchar2(4000); 
    Output varchar2(4000); 

-- this routine build the list of comma seperated authorized users 

BEGIN 

SELECT NN_Name,  
     nvl(replace(Upper(LISTAGG(Name, ',') WITHIN GROUP (ORDER BY Name)), '@XYZ.COM', NULL), 'NO_DATA') AS Names 
     into thisName, Output 
FROM (
    SELECT DISTINCT(NN_NAME), 
     Name 
    FROM LINE_ITEMS 
    UNPIVOT(name FOR typ IN ( 
     FMW_MGR_L3_EMAIL, 
     FMW_MGR_L4_EMAIL, 
     FMW_MGR_L5_EMAIL, 
     FMW_MGR_L6_EMAIL, 
     FMW_MGR_L7_EMAIL, 
     FMW_EMAIL, 
     HYBRID_MGR_L3_EMAIL, 
     HYBRID_MGR_L4_EMAIL, 
     HYBRID_MGR_L5_EMAIL, 
     HYBRID_MGR_L6_EMAIL, 
     HYBRID_MGR_L7_EMAIL, 
     HYBRID_REP, 
     TECH_MGR_L3_EMAIL, 
     TECH_MGR_L4_EMAIL, 
     TECH_MGR_L5_EMAIL, 
     TECH_MGR_L6_EMAIL, 
     TECH_MGR_L7_EMAIL, 
     TECH_EMAIL) 
    )) 
where NN_NAME = nn1 
GROUP BY NN_NAME; 

EXCEPTION 
    WHEN no_data_found then  
    Output := 'NO_DATA'; 

return Output; 


END; 

我的EXCEPTION HANDLING代碼有問題,但我無法確定它是什麼。任何幫助感謝!

回答

2

在發生異常之前,您不會返回任何值。

那麼你應該低於EXCEPTION

Output := 'NO_DATA'; 
return Output; 

添加

return Output; 

的陳述時,NO_DATA_FOUND觸發只執行。

所以,你的代碼應該像

BEGIN 
     SELECT NN_Name,  
       nvl(replace(Upper(LISTAGG(Name, ',') WITHIN GROUP (ORDER BY Name)), '@XYZ.COM', NULL), 'NO_DATA') AS Names 
       into thisName, Output 
     FROM (
      --skipped) 
      )) 
     where NN_NAME = nn1 
     GROUP BY NN_NAME; 
     return Output; --  <--- code added 
    EXCEPTION 
     WHEN no_data_found then  
     Output := 'NO_DATA'; 
     return Output; 
    END; 
+0

所以,你還需要'返回輸出;'了'EXCEPTION'塊之前。 – mathguy

+0

那是我的罪魁禍首。謝謝! – user1009073

4

你的困惑是在這裏:

EXCEPTION 
    WHEN no_data_found then  
    Output := 'NO_DATA'; 

return Output; 

WHEN條款不會終止,直到它擊中另一WHEN或與END。所以你的return Output;是異常處理程序的一部分,不是代碼主體的一部分。 (你縮進代碼的方式可能會產生這樣的印象,即return語句在異常處理程序之外,但編譯器並不在意這一點,只是關於定義的語法。)

我會建議稍微不同修復比在其他答案,以避免有多個返回語句。您可以嵌套BEGIN/END塊來完成你想要的流量:

BEGIN 
    BEGIN 
    ... SQL statement here... 
    EXCEPTION 
    WHEN no_data_found then  
     Output := 'NO_DATA'; 
    END; 

    return Output; 
END;