创建游标和过程
Creating a Cursor and Procedure
我为过程创建了一个 Cursor。我正在尝试将标志应用于该游标中的记录。
Create or Replace Procedure Pledges
(IDdonor In Int)
is
Cursor Cur_Pledges is
Select dd_pledge.iddonor, dd_status.idstatus from dd_donor
join dd_pledge on dd_donor.iddonor=dd_pledge.iddonor
join dd_status on dd_pledge.idstatus=dd_status.idstatus;
Type All_Pledges2 is record(iddonor dd_pledge.iddonor%type, idstatus dd_status.idstatus%type, flag Varchar2(10));
Begin
For Rec_Pledges in Cur_Pledges LOOP
if rec_pledges.idstatus = '10' THEN Flag := 'True';
elsif rec_pledges.idstatus= '20' THEN Flag := 'False';
End if;
Insert Into All_Pledges
Values(rec_pledges.idddonor, rec_pledges.idstatus, flag);
End Loop;
End;
您错误地使用了类型记录变量,我已经进行了更改,请在下面检查,这会起作用:
Create or Replace Procedure Pledges
(IDdonor In Int)
is
Cursor Cur_Pledges is
Select dd_pledge.iddonor, dd_status.idstatus from dd_donor
join dd_pledge on dd_donor.iddonor=dd_pledge.iddonor
join dd_status on dd_pledge.idstatus=dd_status.idstatus;
Type All_Pledges2 is record(iddonor dd_pledge.iddonor%type, idstatus dd_status.idstatus%type, flag Varchar2(10));
-- new change below
allpledges2 All_Pledges2;
Begin
For Rec_Pledges in Cur_Pledges LOOP
if rec_pledges.idstatus = '10' THEN
allpledges2.Flag := 'True';
elsif rec_pledges.idstatus= '20' THEN
allpledges2.Flag := 'False';
End if;
Insert Into All_Pledges
Values(rec_pledges.iddonor, rec_pledges.idstatus, allpledges2.flag);
End Loop;
End;
虽然您可以使用游标循环执行此操作,但您不应该这样做。通常,如果您最大限度地减少上下文更改的数量并让 SQL 优化器完成它的工作,PL/SQL 性能最佳。此过程应由单个 insert
语句组成:
CREATE OR REPLACE PROCEDURE pledges (iddonor IN INT) IS
BEGIN
INSERT INTO all_pledges
SELECT dd_pledge.iddonor,
dd_status.idstatus,
CASE dd_status.idstatus
WHEN '10' THEN 'True'
WHEN '20' THEN 'False'
END
FROM dd_donor
JOIN dd_pledge ON dd_donor.iddonor = dd_pledge.iddonor
JOIN dd_status ON dd_pledge.idstatus = dd_status.idstatus;
END pledges;
可能值得注意的是,正如所写,iddonor
参数是多余的:因为您没有在代码中引用它,所以它没有任何用处。
如果目标只是将结果 return 到另一个程序,则根本不需要插入(使用 table 到 return 结果集不是Oracle 中的一个很好的模式)。处理该问题的最佳方法通常是打开一个引用游标,然后 return that:
CREATE OR REPLACE PROCEDURE pledges (iddonor IN INT,
all_pledges OUT SYS_REFCURSOR) IS
BEGIN
OPEN all_pledges FOR
SELECT dd_pledge.iddonor,
dd_status.idstatus,
CASE dd_status.idstatus
WHEN '10' THEN 'True'
WHEN '20' THEN 'False'
END
FROM dd_donor
JOIN dd_pledge ON dd_donor.iddonor = dd_pledge.iddonor
JOIN dd_status ON dd_pledge.idstatus = dd_status.idstatus
WHERE dd_donor.iddonor = pledges.iddonor;
END pledges;
或者,您可以 return 用户定义类型或将结果写入全局临时 table。
我为过程创建了一个 Cursor。我正在尝试将标志应用于该游标中的记录。
Create or Replace Procedure Pledges
(IDdonor In Int)
is
Cursor Cur_Pledges is
Select dd_pledge.iddonor, dd_status.idstatus from dd_donor
join dd_pledge on dd_donor.iddonor=dd_pledge.iddonor
join dd_status on dd_pledge.idstatus=dd_status.idstatus;
Type All_Pledges2 is record(iddonor dd_pledge.iddonor%type, idstatus dd_status.idstatus%type, flag Varchar2(10));
Begin
For Rec_Pledges in Cur_Pledges LOOP
if rec_pledges.idstatus = '10' THEN Flag := 'True';
elsif rec_pledges.idstatus= '20' THEN Flag := 'False';
End if;
Insert Into All_Pledges
Values(rec_pledges.idddonor, rec_pledges.idstatus, flag);
End Loop;
End;
您错误地使用了类型记录变量,我已经进行了更改,请在下面检查,这会起作用:
Create or Replace Procedure Pledges
(IDdonor In Int)
is
Cursor Cur_Pledges is
Select dd_pledge.iddonor, dd_status.idstatus from dd_donor
join dd_pledge on dd_donor.iddonor=dd_pledge.iddonor
join dd_status on dd_pledge.idstatus=dd_status.idstatus;
Type All_Pledges2 is record(iddonor dd_pledge.iddonor%type, idstatus dd_status.idstatus%type, flag Varchar2(10));
-- new change below
allpledges2 All_Pledges2;
Begin
For Rec_Pledges in Cur_Pledges LOOP
if rec_pledges.idstatus = '10' THEN
allpledges2.Flag := 'True';
elsif rec_pledges.idstatus= '20' THEN
allpledges2.Flag := 'False';
End if;
Insert Into All_Pledges
Values(rec_pledges.iddonor, rec_pledges.idstatus, allpledges2.flag);
End Loop;
End;
虽然您可以使用游标循环执行此操作,但您不应该这样做。通常,如果您最大限度地减少上下文更改的数量并让 SQL 优化器完成它的工作,PL/SQL 性能最佳。此过程应由单个 insert
语句组成:
CREATE OR REPLACE PROCEDURE pledges (iddonor IN INT) IS
BEGIN
INSERT INTO all_pledges
SELECT dd_pledge.iddonor,
dd_status.idstatus,
CASE dd_status.idstatus
WHEN '10' THEN 'True'
WHEN '20' THEN 'False'
END
FROM dd_donor
JOIN dd_pledge ON dd_donor.iddonor = dd_pledge.iddonor
JOIN dd_status ON dd_pledge.idstatus = dd_status.idstatus;
END pledges;
可能值得注意的是,正如所写,iddonor
参数是多余的:因为您没有在代码中引用它,所以它没有任何用处。
如果目标只是将结果 return 到另一个程序,则根本不需要插入(使用 table 到 return 结果集不是Oracle 中的一个很好的模式)。处理该问题的最佳方法通常是打开一个引用游标,然后 return that:
CREATE OR REPLACE PROCEDURE pledges (iddonor IN INT,
all_pledges OUT SYS_REFCURSOR) IS
BEGIN
OPEN all_pledges FOR
SELECT dd_pledge.iddonor,
dd_status.idstatus,
CASE dd_status.idstatus
WHEN '10' THEN 'True'
WHEN '20' THEN 'False'
END
FROM dd_donor
JOIN dd_pledge ON dd_donor.iddonor = dd_pledge.iddonor
JOIN dd_status ON dd_pledge.idstatus = dd_status.idstatus
WHERE dd_donor.iddonor = pledges.iddonor;
END pledges;
或者,您可以 return 用户定义类型或将结果写入全局临时 table。