2017-02-09 95 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,它会适合我在其他场合! –