创建光标和过程

Posted

技术标签:

【中文标题】创建光标和过程【英文标题】:Creating a Cursor and Procedure 【发布时间】:2015-03-24 03:35:05 【问题描述】:

我为一个过程创建了一个光标。我正在尝试将标志应用于该游标中的记录。

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;

【问题讨论】:

请用不工作的地方、你得到的结果(和你期望的)、错误消息来扩展帖子。这可能会降低潜在回答者找到答案的门槛。当您进行修改时,不要在您的问题中添加 EditUpdate 之类的内容。本站有编辑历史,需要查看差异的可以从那里获取信息。 【参考方案1】:

您错误地使用了类型记录变量,我已进行了更改,请检查以下内容,这将起作用:

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;

【讨论】:

已按照建议进行了更改,但仍然收到错误 - 'Values(rec_pledges.iddonor, rec_pledges.idstatus, allpledges2.flag); ' 我收到的错误是 SQL 语句被忽略并且 PL/SQL 表或视图不存在 有表 all_pledges 吗?如果没有,那么您必须先创建。【参考方案2】:

虽然您可以使用游标循环来执行此操作,但您不应该这样做。通常,如果您将上下文更改的次数降至最低并让 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 参数是多余的:因为您没有在代码中引用它,所以它没有任何作用。


如果目标只是简单地将结果返回到另一个程序,则根本不需要插入(使用表返回结果集在 Oracle 中不是一个好的模式)。处理这个问题的最好方法通常是打开一个引用游标并返回它:

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;

或者,您可以返回用户定义的类型或将结果写入全局临时表。

【讨论】:

感谢您的回复。我需要创建一个程序,该程序将使用donorid 作为将传递给该程序的参数。我实际上不想创建一个永久表,一旦光标完成,我就可以使用它来显示结果

以上是关于创建光标和过程的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL存储过程,函数,光标

DB2 - 在光标中聚合大小写

在带有 oracle 光标的过程中使用用户定义的函数

程序主体内的光标

C# 和 PlSql 光标

拖放DataGrid中下降,拖动过程中自定义光标不工作