【问题标题】:Updating database records in a loop?循环更新数据库记录?
【发布时间】:2010-10-08 01:53:43
【问题描述】:
declare
begin
  for i in (select * from emp)
  loop
    if i.sal=1300 then
      update emp
      set sal=13000;
    end if;
  end loop;
end;

此代码正在更新工资为 13000 的所有记录。
相反,我想将工资为 1300 的记录更新为值 13000。
你能告诉我哪里出错了吗?
我正在使用隐式游标访问记录..
对于每条记录,我都在检查该记录的 Sal 值。
如果特定记录中的工资值为 1500,我想将其更新为 15000..

【问题讨论】:

    标签: sql plsql


    【解决方案1】:

    删除该代码并使用:

    update emp set sal = 13000 where sal = 1300
    

    【讨论】:

      【解决方案2】:

      只要您可以使用一条语句进行更新,您就应该这样做,而不是使用循环。这样,您将获得非常巨大的性能提升;或者,反过来,循环更新会消耗大量性能。

      如果你真的必须使用循环,当然你需要一个 where 条件来确保你只更新你真正想要更新的记录。一种始终有效的可能方法(即使没有可用的唯一键)是使用 rowid 伪列:

      begin
        for i in (select rowid, emp.* from emp)
        loop
          if i.sal=1300 then
            update emp
            set sal=13000
            where rowid=i.rowid;
          end if;
        end loop;
      end;
      

      另一种可能性是使用显式游标和“update ... where current of cursorname”语法。

      【讨论】:

        【解决方案3】:

        您需要对更新语句施加约束。

        你现在拥有的将遍历结果行,如果它找到一个工资等于 1300 的行,然后执行他下面的 SQL:

        update emp 
        set sal=13000;

        没有约束,这会更新每一行。

        【讨论】:

          【解决方案4】:

          此代码正在更新工资为 13000 的所有记录。 相反,我想将薪水为 1300 的记录更新为值 13000。

          对于每条记录,我都在检查该记录的 Sal 值。 如果特定记录中的工资值为 1500,我想将其更新为 15000..

          那么你到底想要什么?

          你只想更新 1500 工资,你发出:

          UPDATE emp
          SET sal = 15000
          WHERE sal = 1500;
          

          你要全部加薪十倍,你发出:

          UPDATE emp
          SET sal = sal * 10;
          

          【讨论】:

            【解决方案5】:

            虽然其中一些解决方案是可行的,但它并不是一刀切的解决方案。我遇到了一个场景,我们必须在具有 +50 M 记录的表上将 xml/nvarchar(max) 字段设置为 null。这是代码的摘录

            begin
            
            declare @rows int,
                    @y    int = 2020,
                    @m    int = 1;
            
            set @rows = 1;
            
            while (@rows > 0)
            begin
            
            update top (500) cr
               set [xml] = null
             from [dbo].[customer] cr with(index(ix_customer_reportdt)) 
             where  year([reportdt]) = @y
               and month([reportdt]) = @m
               and [xml] is not null;
            
              set @rows = @@rowcount;
            
            end
            
            end
            

            【讨论】:

              【解决方案6】:

              这是一个快速解决方案,有助于根据创建日期删除列数据的空格(修剪):

              UPDATE table_Name SET column_name = LTRIM(RTRIM(column_name)) 
              WHERE EXTEND(dateTime_column, YEAR TO DAY)='2020-01-31' ;
              

              【讨论】:

                猜你喜欢
                • 2012-12-30
                • 1970-01-01
                • 2013-07-13
                • 2016-12-07
                • 1970-01-01
                • 2016-01-15
                • 1970-01-01
                • 1970-01-01
                • 2018-06-08
                相关资源
                最近更新 更多