2017-02-09 127 views
0

我有一個使用cursor的功能,而這cursor由功能paramenters初始化比較:甲骨文 - 與空警告

FUNCTION get_keys(p_1 IN VARCHAR) 
        RETURN VARCHAR AS 
p_result VARCHAR(5000); 

CURSOR crs_keys IS 
    SELECT  key_name 
    FROM  table_keys 
    WHERE  key = '' || p_1 || ''; 

BEGIN 
p_result := '1'; 
return p_result; 
END get_key_columns; 

在編譯時,我得到的華林:

comparison with null in get_keys 
    WHERE  key = '' || p_1 || '' 

我已經嘗試在p_1'' || nvl(p_1, 'some test value') || ''中設置默認值。但我無法擺脫這個警告。

謝謝。

+0

函數名稱不匹配:get_keys與get_key_columns,我不明白在12c上編譯。該片段是否完整? – dlatikay

+2

你爲什麼要在你的光標中連接NULL('')到p_1?如果你試圖用引號括住p_1,你需要使用'''''|| p_1 ||''''(但是因爲p_1已經是VARCHAR了,所以我不明白你爲什麼要這樣做) –

回答

2

當你寫,

WHERE key = '' || p_1 || ''; 

兩個單引號是一個空字符串,其計算結果爲NULL。和NULL concat的東西產生NULL。

簡單地寫,

WHERE key=p_1; 

如果意圖是包圍在文字引號P_1的價值,通過轉義引號這樣做,或要求其在已通過參數有此其價值。

+2

用串連接的NULL不等於NULL。 SELECT''||'f'||''FROM dual將返回f。 –

+0

oops。對。這使這個答案的第一部分無效。讓我們看看我們是否可以在OP中獲得更多關於連接意圖的信息。 – dlatikay

+0

解決方案非常明顯,但我看不到它。謝謝。 –

1

使用參數化遊標它是更好更安全的方法。 例

declare 
     cursor test_cur(l_name in varchar) is 
     select l_name from dual; 
    l_out varchar(1024); 


    begin 
    open test_cur('John'); 
    loop 
     fetch test_cur into l_out; 

     if test_cur%notfound then 
     close test_cur; 
     exit; 
     end if; 

     DBMS_OUTPUT.PUT_LINE(l_out); 
    end loop; 
    end; 
/

你修改後的代碼

create or replace FUNCTION get_keys(p_1 IN VARCHAR) 
        RETURN VARCHAR AS 
p_result VARCHAR(5000); 

CURSOR crs_keys(p_cur in varchar) IS 
    SELECT  key_name 
    FROM  table_keys 
    WHERE  key = p_cur 
or (p_cur is null and key is null); --comparing with null 

BEGIN 
open crs_keys(p_1); 
    loop 
     fetch crs_keys into p_result; 

     if crs_keys%notfound then 
     close crs_keys; 
     exit; 
     end if; 

     DBMS_OUTPUT.PUT_LINE(p_result); 
    end loop; 
p_result := '1'; 
return p_result; 
END get_keys; 
+0

我'我不確定我是否同意你的觀點 - 沒有什麼比遊標參數更安全或更好的了。在問題中沒有什麼建議LOOP是合適的(如果你想要一個循環,爲什麼不使用CURSOR FOR LOOP?) –

+0

這只是一個簡單的例子 - 請使用CURSOR FOR LOOP或任何其他方式 - 由你決定。它只是顯示瞭如何使用光標參數 – Jgrammer

+0

感謝您的answare,它會適合我在其他場合! –