在循环中更新数据库记录?

时间:2009-02-17 12:15:24

标签: sql plsql

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 ..

6 个答案:

答案 0 :(得分:26)

删除该代码,然后使用:

update emp set sal = 13000 where sal = 1300

答案 1 :(得分:11)

每当您可以使用一个语句执行更新时,您应该这样做而不是使用循环。你将获得非常巨大的性能提升;或者反过来说,循环中的更新会让你失去很多性能。

如果你真的必须使用一个循环,当然你需要一个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;

另一种可能性是使用显式游标和“更新......其中 cursorname 的当前值”语法。

答案 2 :(得分:5)

您需要在更新语句上设置约束。

您目前所拥有的内容将循环遍历结果行,如果它找到一个薪水等于1300的行,那么执行时他会跟随SQL:

update emp 
set sal=13000;

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

答案 3 :(得分:5)

  

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

     

我正在检查该记录的sal值。   如果特定记录中的工资值是1500,我想将其更新为15000 ..

那你究竟想要什么?

您只想更新1,500个工资,您可以发出:

UPDATE emp
SET sal = 15000
WHERE sal = 1500;

你想要增加所有工资十倍,你发出:

UPDATE emp
SET sal = sal * 10;

答案 4 :(得分:1)

尽管其中一些解决方案可行,但并非所有解决方案都适用。我遇到了一种情况,我们必须在具有+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

答案 5 :(得分:0)

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

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