【问题标题】:SQL: Update All Selected RowsSQL:更新所有选定的行
【发布时间】:2013-03-12 18:35:45
【问题描述】:

在下面的代码中。一次只会执行一个“选择”语句。我希望能够更新任何选定行的“状态”并返回数据。这基本上可以防止在后端处理期间获取相同的记录。

谢谢!

-- Insert statements for procedure here
if(@BatchSize > -1 and @Priority > -1)
begin
    Select TOP(@BatchSize) *,ID 
    From CompingQueue 
    Where PriorityLevel=@Priority 
       and Status=35 
    order by PriorityLevel asc;
end
if(@BatchSize = -1 and @Priority = -1)
begin
    Select * From CompingQueue 
    Where Status=35 
    order by PriorityLevel asc;
end

if(@BatchSize = -1 and @Priority > -1)
begin
   Select * From CompingQueue 
   WHEre PriorityLevel=@Priority 
     and Status=35     
   order by PriorityLevel asc;
end
if(@BatchSize > -1 and @Priority = -1)
begin
    Select TOP(@BatchSize) * 
    From CompingQueue 
    Where Status=35 
    order by PriorityLevel asc;
end
--update CompingQueue set Status = 2 where ID=
-- Set the Status Flag for each job

结束

【问题讨论】:

    标签: sql sql-server select sql-update


    【解决方案1】:

    我会使用 DECLARE @tblResults TABLE (...)。将 SELECT 行插入到表变量中。在 PK 上执行从源表到表变量的联接,将此联接用作 UPDATE 语句中的子句,然后将变量作为查询/proc/func 结果返回。

    【讨论】:

    • 您甚至不需要将所有行存储在@tblResults 中,您只需存储主键即可。
    【解决方案2】:

    一种选择是仅UPDATE 表并使用OUTPUT 将更新的行存储在表变量中。然后您可以SELECT 或进一步处理表变量中的数据。

    documentation中有一个例子。

    【讨论】:

      【解决方案3】:

      您想要OUTPUT 子句。

      http://msdn.microsoft.com/en-us/library/ms177564.aspx

      听起来你想要类似的东西

      UPDATE c
      SET somestuff = something
      OUTPUT DELETED.*
      FROM CompingQueue c
      WHERE someotherstuff
      

      或者,如果您想要更新后的数据,请使用 INSERTED.* 而不是 DELETED.*

      【讨论】:

        【解决方案4】:

        像这样一次性完成它们怎么样:

        Declare @NumRecs int
        if @BatchSize > -1 Set @NumRecs = @BatchSize 
        else Select @NumRecs = Count(*) From CompingQueue 
        -- --------------------------
        Declare @Ids table (id int primary key not null)
        Insert @Ids(id)
        Select top(@numRecs) id 
        From CompingQueue 
        Where Status=35 
           And PriorityLevel = Case 
              When @Priority > -1 Then @Priority 
              Else PriorityLevel End
        Order by PriorityLevel asc;
        
         Select * From CompingQueue 
         Where Id In (Select id from @Ids);
        
         Update CompingQueue Set
            status = 2
         Where Id In (Select id from @Ids);
        

        【讨论】:

          【解决方案5】:

          SQL CTE 将为您的案例提供帮助。您正在尝试避免并发问题,因为多个进程可能会更新相同的记录。在您的查询中,您拥有最高批次,因此直接更新...输出可能不是最佳选择。 CTE + xlock,rowlock 会是更好的选择

          
          ;with Update_batch 
          as 
          (
            select top 10 * from compingqueue With (xlock, rowlock)
            order by PriorityLevel desc
          )
          update Update_batch
          set ....=....
          
          You can treat CTE as on-fly view, with (xlock, rowlock), when rows are selected, an (xlock, rowlock) will be put on the row, which将确保其他进程甚至无法获得相同的行。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-29
            • 1970-01-01
            • 1970-01-01
            • 2012-01-23
            • 1970-01-01
            相关资源
            最近更新 更多