尽管where子句,Oracle游标返回表中的所有行

时间:2012-02-07 14:10:07

标签: oracle cursor

我使用以下查询返回单个值:

select er.elig_code
from idm_elig_rule er 
where ER.ROLE_CODE = role_code and ER.SERVICE_CODE = service_code; 

当我替换变量的值并将其作为单个SQL语句运行时,它将只返回一个我想要的值。但是,当我将语句放在游标中并遍历结果时,它将返回表中的所有行。我还尝试了一个“select into”语句,但仍然返回表中的所有85行。我在idm_elig_rule表中有一个唯一索引,它是role_code,service_code和另一列的组合。

编辑:这是我如何测试它 - 使用匿名块:

declare
    role_code_in IDM_ELIG_RULE.ROLE_CODE%type := 'CEMP';
    service_code_in IDM_ELIG_RULE.SERVICE_CODE%type := 'PORTL'; 
    cursor get_elig_code is 
        select ER.ELIG_CODE
        from idm_elig_rule er 
        where ER.ROLE_CODE = role_code_in and ER.SERVICE_CODE = service_code_in; 
begin 
    for r in get_elig_code 
    loop
        DBMS_OUTPUT.PUT_LINE(r.elig_code);
    end loop;  
end;

编辑:我在where子句中更改了变量的名称并解决了问题。

3 个答案:

答案 0 :(得分:9)

您的变量名称存在名称解析问题,因为绑定变量名称与列名称相同。更改变量名称以避免PL / SQL编译器为您决定。

Oracle PL/SQL Variable Name Resolution

答案 1 :(得分:3)

由于您的变量名与列名相同,因此解析器可能会将它们视为列名而不是变量,因此您将获得列与其自身相等的所有行,只会排除具有NULL值的行。

我建议为变量使用不同的名称而不是列,以避免混淆。一种常见的技术是在变量名称上使用一些前缀,例如l_表示局部变量,p_表示参数,或g_表示全局变量。

在这种情况下,最好参数化光标:

CURSOR code_cur (p_role_code INTEGER, p_service_code INTEGER) IS
select er.elig_code
from idm_elig_rule er 
where ER.ROLE_CODE = p_role_code and ER.SERVICE_CODE = p_service_code;

然后在打开光标时传递值,例如:

FOR code_rec IN code_cur ( my_role_code_value, my_service_code_value ) LOOP

答案 2 :(得分:3)

根据您问题中的有限信息,我会说您的参数未正确实例化,并且您的选择正在解析为:

select er.elig_code
  from idm_elig_rule er
 where ER.ROLE_CODE = role_code 
   and ER.SERVICE_CODE = service_code; 

如果数据库看到role_codeservice_code作为列而不是变量,那么它将始终返回表中的所有行。

将变量名称更改为与列名称不同的名称,以查看是否属于这种情况。