【问题标题】:How to update other OrderNo when I update OrderNo of one record on tsql当我在 tsql 上更新一条记录的 OrderNo 时如何更新其他 OrderNo
【发布时间】:2019-05-29 14:42:50
【问题描述】:

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

我在更新 OrderNo 时遇到了问题。

如果我更新了其中一个 OrderNo,则必须更新所有 OrderNo 取决于更新后的 OrderNo,因此所有订单都会更新。

解决方案之一是光标,但我没有解决这个问题。

你有什么建议吗?

【问题讨论】:

  • 嗨,如果你想要最好的答案,或者任何答案,请查看this questionthis question
  • @BarryPiccinni 谢谢你的回答,但这是 sql 的一种常见问题
  • 您在寻找什么行为?例如,如果您将 10 更改为 3,您是否正在寻找数字 >=3 和
  • @user7733611 您的评论几乎满足了我的要求。你对解决方案有什么想法吗
  • 是的。它将帮助您提出更好的问题,进而帮助您获得更好的答案。

标签: sql tsql sql-update cursor


【解决方案1】:

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

注意:它应该被包装在一个合适的交易中,以便在 The Real Word 中使用。

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

【讨论】:

  • 感谢您的解决方案,但此脚本中忽略了空值。此外,如果 DisplayOrder 值相等,则它不起作用。您的脚本仅适用于相同的 DisplayOrder 值。我将尝试在这些方面进行开发
  • @MertMetin 您的问题不清楚Questions 包含具有相同OrderNo、null OrderNo、...的行。我疯狂地假设这些值是从1 开始的整数,并以密集的方式进行直到行数。事实上,问题的重点似乎是更新OrderNo,这样多个问题就不会具有相同的价值。请阅读this 了解一些改进问题的技巧。
猜你喜欢
  • 1970-01-01
  • 2013-10-26
  • 2014-09-01
  • 2016-07-29
  • 2018-11-20
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多