【问题标题】:how can I update the record in this case?在这种情况下如何更新记录?
【发布时间】:2011-04-26 10:08:23
【问题描述】:

我将 ID 为 1、2、3、4 的各种活动连续存储。

如果我删除第二条记录(id 2),我如何更新以使 3 变为 2 并且 4 变为 3?

提前致谢

【问题讨论】:

  • 为什么需要这样做?有没有缝隙应该没关系。如果您需要从 id 派生连续的数字序列,Oracle 和 SQL Server 都支持ROW_NUMBER
  • 问题不是如何,而是为什么?你想通过保证表中存储和维护的连续数字来实现什么?
  • frds...这是fjords的缩写吗?

标签: sql sql-server oracle sql-server-2005 tsql


【解决方案1】:
update table set col1 = col1-1 where col1>2

【讨论】:

  • 如果 OP 在 SQL Server 中使用实际的 identity 列,这将不起作用,因为它们不可更新。
  • @Martin - 没错,你无法改变
  • 什么是OP?这里请告诉我
  • “OP”的意思是“原创者”——在本例中是你。
【解决方案2】:

答案 1. 你不想。 id 字段的全部目的是它是不可变的。

回答 2。你不想。如果需要,id 字段根本不是 id 字段,而是数据字段。

答案 3. 删除记录并用新号码重新插入。 您可以看到,如果行数很大,这会变得非常昂贵。

【讨论】:

  • 很多情况下,如果删除再重新插入,被删除的id不会被重用,而是会使用序列中新的未使用的id
【解决方案3】:

改用linked list 方法怎么样,每个活动都指向下一个活动?

select * from activity;
+----+---------+
| id | next_id |
+----+---------+
|  1 |       2 |
|  2 |       3 |
|  3 |       4 |
|  4 |       5 |
|  5 |    NULL |
+----+---------+

如果要删除 ID=2 的活动,需要将 ID=2 指向的行更新为 ID=2 之前指向的行。

update activity
   set next_id = 3
 where id = 1;

delete
  from activity 
 where id = 2;

+----+---------+
| id | next_id |
+----+---------+
|  1 |       3 |
|  3 |       4 |
|  4 |       5 |
|  5 |    NULL |
+----+---------+

如果您的列表很长并且担心 DML 性能,这可能是一个不错的选择。这种方法的缺点是查询表比较困难。

【讨论】:

  • +1 但这不是更好地描述为singly linked list吗?
  • @oneday,是的,我更新了答案以使用正确的术语。
猜你喜欢
  • 1970-01-01
  • 2021-08-13
  • 1970-01-01
  • 2023-03-15
  • 2015-11-23
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 2022-11-24
相关资源
最近更新 更多