在使用游标时,使用 Oracle SQL 更新记录会导致无限循环

Posted

技术标签:

【中文标题】在使用游标时,使用 Oracle SQL 更新记录会导致无限循环【英文标题】:Updating record with Oracle SQL results in an infinite loop while using a cursor 【发布时间】:2020-02-05 09:48:13 【问题描述】:

我在使用游标更新记录时陷入无限循环。这是代码......我应该怎么做的任何建议?

CREATE OR REPLACE PROCEDURE SHADI.filling_conditional
as
  cursor filling_cursor is select * from deposits_table for update;
begin 
  for i in filling_cursor 
  loop       
       update deposits_table 
         set conditional_flag = case 
                                    when i.deposit_amount > 1000 and i.currency_code = 'JOD'
                                         and (select customer_info.sex 
                                              from customer_info 
                                              where customer_info.customer_number = i.customer_number) = 1 
                                       then 1
                                    else 0 
                                 end;

  end loop;
end filling_conditional;
/

【问题讨论】:

不需要光标。 如果你真的想用最慢的方式来更新一个表,你至少应该在你的update语句中使用where current of。目前,游标的每次迭代都会更新表中的 all 行 - 我很确定这不是你想要的。 我是 oracle 新手,我需要将这个过程作为游标来实现。有任何想法吗?感谢您的回复。 这是一种奇怪的“做法”,教的东西效率低下。 @a_horse_with_no_name 感谢您的回复,我是 Oracle 的新手。主要思想是迭代 deposit_table 中符合上述条件的每一行。并相应地更新它们 【参考方案1】:

请尝试以下程序代码:

CREATE OR REPLACE PROCEDURE SHADI.filling_conditional
as
   c_deposit_amount   deposits_table.deposit_amount%type; 
   c_currency_code deposits_table.currency_code%type; 
   c_customer_number deposits_table.customer_number%type; 
   cursor filling_cursor is select deposit_amount, currency_code, customer_number from deposits_table for update;
BEGIN 
   OPEN filling_cursor; 
   LOOP 
   FETCH filling_cursor into c_deposit_amount, c_currency_code, c_customer_number; 
      EXIT WHEN filling_cursor%notfound; 
      update deposits_table 
         set conditional_flag = case 
                                    when c_deposit_amount > 1000 and c_currency_code = 'JOD'
                                         and (select customer_info.sex 
                                              from customer_info 
                                              where customer_info.customer_number = c_customer_number) = 1 
                                       then 1
                                    else 0 
                                 end;
   END LOOP; 
   CLOSE filling_cursor; 
END filling_conditional;
/

【讨论】:

以下代码产生如下错误:[Error] PLS-00324 (11: 17): PLS-00324: cursor attribute may not be applied to non-cursor 'C_CUSTOMER_NUMBER' 这一行产生的错误:EXIT WHEN c_deposit_amount%notfound; 只需更新代码如下:"EXIT WHEN c_deposit_amount%notfound; => "EXIT WHENfill_cursor%notfound; " 这仍然在为每次迭代更新deposits_table 中的 所有 行,因为 UPDATE 没有 WHERE 子句

以上是关于在使用游标时,使用 Oracle SQL 更新记录会导致无限循环的主要内容,如果未能解决你的问题,请参考以下文章

SQL游标怎么循环更新

Oracle SQL

在 oracle 中使用游标插入和更新记录

Oracle_PL/SQL 游标

如何优化使用游标的 PL/SQL 代码

Oracle 游标