循环不在包中工作

时间:2013-02-14 16:59:41

标签: sql oracle11g oracle-sqldeveloper plsqldeveloper

我有两个表: - 人员和银行详细信息

Person table :---
person_id     employee_number
393829          X1029
648494          x9494
393939          X2299

Bank details :---

person_id       bank_form
393829         Reimb
393829         Sal
648494         Sal
393939         Common

现在,如果某个人的银行形式为“sal”和“reimb”,则必须打印“This is it”。如果他只有“共同”作为银行形式,那么也无需做任何事情。 我为此做了一个光标。但是“这就是它”行不起作用。

Create or replace package body xx_bank_details
as 
procedure xx_bank_details_proc( 
ERRBUF out varchar2,
 RETCODE  out varchar2
)

Cursor c1
is 
select person_id
from person;

Cursor c2(p_person_id)
is select bank_form
from bank_details
where bank_details.person_id=p_person_id;

begin

for cur_c1 in c1
loop
        for cur_c2 in c2(c1.person_id)
        loop
        if(cur_c2.bank_details='Sal')
then
l_sal :='Sal';
end if;
if(cur_c2.bank_details='Reimb')
then
l_reimb :='Reimb';
end if;
if(cur_c2.bank_details='Common')
then
l_common :='Common';
end if;
end loop;
if (l_sal is not null and l_reimb is not null)
then
fnd_output.put_line("This is it !");
end if;

end loop;
end xx_bank_details_proc;
end xx_bank_details;

2 个答案:

答案 0 :(得分:1)

你的代码充满了错误,所以很难知道你是否已经把整个事情放在一起进行stackoverflow发布或什么。你的主要问题是你没有在C1循环的每次迭代中将三个局部变量重置为NULL。

也是你所说的逻辑“但是如果银行表格只是”Sal“没有”Reimb“那么你必须打印它的表”与代码打印出来的代码不匹配,如果两者都存在。

这一切都可以在单个SQL语句中完成,但不需要所有这些游标循环。

答案 1 :(得分:0)

这里的关键是使用SQL来隔离您要对其执行操作的记录。

一种形式是:

begin
for x in (
  select person_id
  from   person
  where  exists (
           select null -- see comment below *
           from   bank_details
           where  bank_details.person_id=person.person_id and
                  bank_form in ('Sal','Reimb')
           having count(*) = 2)
loop
  fnd_output("This is it!)
end loop
end

SQL上有很多变种可行,但关键问题是将逻辑推入SQL而不是游标,尤其是明确的游标。

comment *:在“exists”子查询中,从子查询中投射的值无关紧要。 “exists”正在查看是否有任何行被投影,无论包含多少列或行以及值是什么。选择null,1,“x”或任何其他文字中的任何一个都是等价的,但是选择null是一种很好的方式,可以说“它与价值无关”。