在tsql上更新一条记录的OrderNo时如何更新其他OrderNo

在tsql上更新一条记录的OrderNo时如何更新其他OrderNo,sql,tsql,sql-update,cursor,Sql,Tsql,Sql Update,Cursor,我有一个名为Questions的问题表,它的OrderNo定义了问题的顺序 我在更新OrderNo时遇到了一个问题 如果我更新其中一个订单号,则必须更新该订单号。所有订单号取决于更新的订单号,因此所有订单都将更新 解决方法之一是游标,但我没有解决这个问题 您有什么建议吗?下面的代码演示了一种方法,可以按照给定的显示顺序重新定位一行,并洗牌任何其他行以适应更改。通过使用case表达式,单个update语句可以选择如何更新不同的行 注意:它应该包装在一个合适的事务中,以便在真实的世界中使用 -- S

我有一个名为Questions的问题表,它的OrderNo定义了问题的顺序

我在更新OrderNo时遇到了一个问题

如果我更新其中一个订单号,则必须更新该订单号。所有订单号取决于更新的订单号,因此所有订单都将更新

解决方法之一是游标,但我没有解决这个问题


您有什么建议吗?

下面的代码演示了一种方法,可以按照给定的显示顺序重新定位一行,并洗牌任何其他行以适应更改。通过使用case表达式,单个update语句可以选择如何更新不同的行

注意:它应该包装在一个合适的事务中,以便在真实的世界中使用

-- Sample data.
declare @Samples as Table ( Id Int Identity, DisplayOrder Int );
insert into @Samples ( DisplayOrder ) values ( 1 ), ( 2 ), ( 3 ), ( 4 );
select * from @Samples order by DisplayOrder;

-- We need a few variables.
declare @PreviousDisplayOrder as Int;
declare @Id as Int, -- Row to be moved.
  @DisplayOrder as Int; -- New order for the row.

-- Pick a row to move and a new display order for it.
select @Id = 2, @DisplayOrder = 3;

-- Determine the previous display order for the row being moved.
select @PreviousDisplayOrder = DisplayOrder from @Samples where Id = @Id;

-- Display some useful tidbits.
select @PreviousDisplayOrder as PreviousDisplayOrder,
  ( select Min( DisplayOrder ) from ( values ( @DisplayOrder ), (@PreviousDisplayOrder ) ) M1( DisplayOrder ) ) as MinDisplayOrder,
  ( select Max( DisplayOrder ) from ( values ( @DisplayOrder ), (@PreviousDisplayOrder ) ) M2( DisplayOrder ) ) as MaxDisplayOrder;

-- Update the rows.
update @Samples
  set DisplayOrder = case
    -- Set the order of the repositioned row.
    when Id = @Id then @DisplayOrder
    -- Moving the repositioned row up (numerically).
    when @DisplayOrder > @PreviousDisplayOrder and DisplayOrder <= @DisplayOrder then DisplayOrder - 1
    -- Moving the repositioned row down (numerically).
    when @DisplayOrder < @PreviousDisplayOrder and DisplayOrder >= @DisplayOrder then DisplayOrder + 1
    else DisplayOrder
    end
    where
      -- Only update the rows between the original and the new display orders.
      DisplayOrder >= ( select Min( DisplayOrder ) from ( values ( @DisplayOrder ), (@PreviousDisplayOrder ) ) M1( DisplayOrder ) ) and
      DisplayOrder <= ( select Max( DisplayOrder ) from ( values ( @DisplayOrder ), (@PreviousDisplayOrder ) ) M2( DisplayOrder ) );

-- Display the results.
select * from @Samples order by DisplayOrder;

您好,如果您想要最好的答案,或者任何答案,请查看并@Barrypicanni感谢您的回答,但这是一种常见问题解答,您在寻找什么行为?例如,如果您将10更改为3,您是否正在查找编号>=3和@user7733611您的评论几乎满足了我的要求。你知道解决方案吗?是的。这将帮助您提出更好的问题,进而帮助您获得更好的答案。感谢您的解决方案,但在此脚本中忽略了空值。此外,如果存在相等的DisplayOrder值,则它不起作用。您的脚本仅适用于相同的DisplayOrder值。我将努力在这些基础上发展regardings@MertMetin从您的问题中不清楚问题包含的行具有相同的OrderNo、null OrderNo、。我疯狂地假设这些值将是从1开始的整数,并以密集的方式进行到行数。事实上,问题的重点似乎是更新OrderNo,这样多个问题就不会有相同的值。请阅读一些关于改进您的问题的提示。