0

我有两张桌子: - 个人和银行详细信息

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”。如果他只有“common”作为银行表格,则也无需执行任何操作。我为此做了一个光标。但是“这就是它”行不起作用。

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;
4

2 回答 2

1

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

您的逻辑也如所述“但如果银行表格只有“Sal”而没有“Reimb”,那么您必须打印出来的表格”与代码不匹配,因为如果两者都存在,则代码正在打印出来。

这整个事情可以在一个单独的 SQL 语句中完成,尽管不需要所有这些游标循环。

于 2013-02-14T17:16:38.167 回答
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 而不是游标,尤其是显式游标。

评论 * :在“存在”子查询中,从子查询投影的值无关紧要。“存在”正在查看是否投影了任何行,无论包含多少列或行以及值是什么。选择 null、1、“x”或任何其他文字中的任何一个都是等效的,但选择 null 是一种很好的说法,即“值是什么并不重要”。

于 2013-02-14T17:07:25.350 回答