我有两个表: - 人员和银行详细信息
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;
答案 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是一种很好的方式,可以说“它与价值无关”。