【问题标题】:How to update more than 1000 records in SQL Server by LOOP?如何通过 LOOP 更新 SQL Server 中的 1000 多条记录?
【发布时间】:2015-10-24 04:50:10
【问题描述】:

我需要更新超过 1000 条记录。这些值在另一个表中。

我试过这个查询:

Update tblEnrollment
SET TrOOPCurrentYrBalanceAmt = tr.TrOOPCurrentYrBalanceAmt
from tblTrOOPbalance tr
join tblMember mem on tr.MedicareNumber = mem.MANumber
join tblEnrollment enr on mem.MemberID = enr.MemberID
where enr.EnrollmentID IN ('16823', '16828')

但我得到一个错误:

消息 512,级别 16,状态 1,过程 tblEnrollment_UpdateTrigger,第 9 行
子查询返回超过 1 个值。
当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

我想我不能用查询更新超过 1 个。如何更新多条记录?

谢谢,

因为tblenrollment表有一个触发器,防止更新多条记录,我只好用LOOP来一条一条地更新一条记录。 任何人都可以帮助如何编写 LOOP 查询吗?

【问题讨论】:

  • 程序 tblEnrollment_UpdateTrigger 中还有其他代码吗?
  • 您的update 语句没有子查询,因此不会产生该错误。
  • 请发布您的所有 SQL 查询代码。以便我们为您提供准确的答案。正如@GordonLinoff 所说,上述查询应该可以正常工作,因为它没有任何子查询来返回数据。
  • 我不知道 tblEnrollment_UpdateTrigger 导致了错误。我在数据库中搜索它,发现它是一个触发器..我什至不知道触发器是什么......无论如何我要再挖掘一些,看看我能找到什么,我会更新。感谢您的帮助!
  • 编写触发器的经典错误。

标签: sql sql-server sql-update


【解决方案1】:

当然,您可以更新多条记录!!!
您的过程tblEnrollment_UpdateTrigger 中似乎还有其他代码,并且子查询存在问题。请检查您是否没有类似的情况 sabquery 将返回超过 1 条记录:

  • where column = (select column2 from table)
  • update tab set column = (select column2 from table)
  • select @variable = (select column2 from table)

关于UPDATE 声明,我认为使用类似的东西会更好:

update enr
set    enr.TrOOPCurrentYrBalanceAmt = tr.TrOOPCurrentYrBalanceAmt
from   tblEnrollment enr
join   tblMember mem on enr.MemberID = mem.MemberID
join   tblTrOOPbalance tr on mem.MANumber = tr.MedicareNumber 
where  enr.EnrollmentID in ('16823','16828')

【讨论】:

    【解决方案2】:

    我相信这个update 更好。 tblEnrollment 是否有主键或唯一列?

    update tblEnrollment
    set TrOOPCurrentYrBalanceAmt = (
        select tr.TrOOPCurrentYrBalanceAmt
        from tblTrOOPbalance tr
        where tr.MemberID = tblEnrollment.MemberID
    )
    where EnrollmentID in ('16823', '16828')
    

    这里有一个可能对一次性修复有用的技巧:

    declare @done bit = 0;
    while @done = 0 begin
    
    update top(1) tblEnrollment
    set TrOOPCurrentYrBalanceAmt = (
        select tr.TrOOPCurrentYrBalanceAmt
        from tblTrOOPbalance tr
        where tr.MemberID = tblEnrollment.MemberID
    )
    where EnrollmentID in ('16823', '16828')
        and coalesce(TrOOPCurrentYrBalanceAmt, -999999) <>
            coalesce((
                select tr.TrOOPCurrentYrBalanceAmt
                from tblTrOOPbalance tr
                where tr.MemberID = tblEnrollment.MemberID
            ), -999999);
    
    set @done = case when @@rowcount = 0 then 1 else 0 end
    end
    

    你可以用这个检查和调试:

    select
        TrOOPCurrentYrBalanceAmt as TrOOPCurrentYrBalanceAmt1,
        (
            select tr.TrOOPCurrentYrBalanceAmt
            from tblTrOOPbalance tr
            where tr.MemberID = tblEnrollment.MemberID
        ) as TrOOPCurrentYrBalanceAmt2
    from tblEnrollment
    where EnrollmentID in ('16823', '16828')
        and coalesce(TrOOPCurrentYrBalanceAmt, -999999) <>
            coalesce((
                select tr.TrOOPCurrentYrBalanceAmt
                from tblTrOOPbalance tr
                where tr.MemberID = tblEnrollment.MemberID
            ), -999999);
    

    【讨论】:

    • 感谢@shawnt00 的帖子。正如我在问题中添加的那样, tblenrollment 表有一个触发器,可以防止更新多条记录。我使用了您的查询,但遇到了同样的错误。我想用LOOP来一一更新。 EnrollmentId 是主键。
    • 我了解触发器的问题,并且我认识到 update 仍然无法自行工作。但是我在回答结束时在循环内使用了这种形式的更新。是那个出错的吗?
    • 如果 EnrollmentId 是主键,那么我认为您应该能够运行第一个脚本两次(每次使用不同的 ID。)
    • 这行得通!谢谢shawnt00。剩下的一个问题是,当我使用您的查询进行更新时。 tblEnrollment 中的空值不会更新。这是为什么?谢谢!
    • 我以为我用合并处理了空值。如果这些正是您需要为其提供值的行,您可以肯定地说and TrOOPCurrentYrBalanceAmt is not null。您可能还需要确保这些子查询确实返回了一个值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    相关资源
    最近更新 更多