2013-03-11 87 views
2

我寫下面FUNCTION檢查給定reference number是否存在。PL/SQL函數返回無值

FUNCTION find_reference_no(
    p_ref_no IN VARCHAR2) RETURN VARCHAR2 
AS 

    v_ref_no varchar2(50); 

BEGIN 

    select REF_NO into v_ref_no from cash where REF_NO = p_ref_no; 
    EXCEPTION 
    WHEN no_data_found THEN 
    v_ref_no := '#'; 

RETURN v_ref_no;  

END; 

我在AFTER INSERT TRIGGER中調用了這個函數。當我插入數據,Ii'm得到錯誤的

ORA-06503: PL/SQL: Function returned without value

我該如何解決這個問題?

PS:我沒有將數據插入到cash表中。我將數據插入另一個表(假設它是表B),並在它的(表B)AFTER INSERT TRIGGER中調用該函數。

+3

這種在觸發器中的查找正是我們應該避免在觸發器中做的那種。這是每個插入的隱藏性能,並且會損害應用程序的可伸縮性。 – APC 2013-03-11 09:15:30

+1

而不是用p_前綴你的參數名稱,考慮在查詢中用參數名稱作爲參數名稱的前綴 - 即。 「where cash.ref_no = find_reference_no.ref_no」。 v_也作爲變量的前綴冗餘,它也應該是數據類型爲cash.ref_no%Type而不是varchar2(50)。 – 2013-03-11 10:08:00

+0

問題不明顯的原因是您的代碼格式錯誤 - RETURN語句*看起來像它是函數正常處理的一部分,而它實際上在函數的EXCEPTION塊內。爲了清楚起見,EXCEPTION關鍵字應該位於左側邊界,與BEGIN和END相同。 – 2013-03-12 03:33:22

回答

8

所有函數都必須執行RETURN語句。您的函數在其異常塊中具有RETURN,因此該語句在正常情況下不會執行。

附加select聲明另加begin end塊自己exception部分將解決您的問題。所以你的功能可能是這樣的:

create or replace function find_reference_no(
    p_ref_no IN VARCHAR2) return varchar2 
AS 
    v_ref_no varchar2(50); 
begin 
    begin 
    select REF_NO 
     into v_ref_no 
     from cash 
     where REF_NO = p_ref_no; 
    exception 
    WHEN no_data_found THEN 
      v_ref_no := '#'; 
    end; 
    return v_ref_no;  
end; 
2

因爲如果在表中存在的函數只是返回相同的值作爲參數,你能避免尷尬的使用異常處理和重寫此爲:

function find_reference_no(
     ref_no in varchar2) 
    return varchar2 
    as 
    row_count integer 
    begin 
    select count(*) 
    into row_count 
    from cash 
    where cash.ref_no = find_reference_no.ref_no and 
      rownum  = 1 

    if row_count = 0 
     return '#' 
    else 
     return ref_no 
    end if; 

    end find_reference_no; 

我會返回一個1或0(即row_count的值)來表明記錄是否存在。

function find_reference_no(
     ref_no in varchar2) 
    return varchar2 
    as 
    row_count integer 
    begin 
    select count(*) 
    into row_count 
    from cash 
    where cash.ref_no = find_reference_no.ref_no and 
      rownum  = 1 

    return row_count 

    end find_reference_no;