3

鉴于以下简单的表结构(SQL Server 2008),我希望能够保持我的数字序列列的唯一性,但我希望能够更新任何给定记录的该值。

CREATE TABLE MYLIST(
      ID int NOT NULL IDENTITY(1, 1)
    , TITLE varchar(50) NOT NULL
    , SEQUENCE int NOT NULL
    , CONSTRAINT pk_mylist_id PRIMARY KEY(ID)
    , CONSTRAINT uq_mylist_sequence UNIQUE(SEQUENCE)
);

我的界面允许我混淆项目的顺序,并且在更新之前我会知道它们应该在哪个非重叠序列中,但是我如何在不违反唯一约束的情况下执行更新?

例如,假设我有这些记录:

ID  TITLE   SEQUENCE
1   APPLE   1
2   BANANA  2
3   CHERRY  3

我想将它们的序列号更新为以下内容:

ID  TITLE   SEQUENCE
1   APPLE   3
2   BANANA  1
3   CHERRY  2

但实际上我可以处理几十个项目。序号不得重叠。我曾考虑过尝试使用触发器或暂时禁用约束,但这似乎会产生更多问题。我正在使用 C# 和 LINQ-to-SQL,但我对严格的数据库解决方案持开放态度。

4

3 回答 3

3

显而易见的方法是批量编写。在内部,SQL 将推迟约束检查,因此中间唯一性无关紧要。

逐行编写没有意义,并且会导致您遇到的问题。

您可以将其更改为写入临时表,然后在最后“刷新”结果,甚至首先检查临时表的唯一性。

DECLARE @NewSeq TABLE (ID int, NewSeq int)

INSERT @NewSeq (ID, NewSeq) VALUES (1, 3)
INSERT @NewSeq (ID, NewSeq) VALUES (2, 1)
INSERT @NewSeq (ID, NewSeq) VALUES (3, 2)

UPDATE
   M
SET
   SEQUENCE = NewSeq
FROM
   MYLIST M
   JOIN
   @NewSeq N ON M.ID = N.ID
于 2011-01-25T20:19:31.677 回答
2

您可以为它们分配正确值的负数,然后在发生所有更新后,在您设置的位置进行最终更新SEQUENCE = -SEQUENCE

不是很有效,但既然你说你只有几十个项目,我怀疑影响会很明显。我还假设您可以使用负数作为“魔术值”来指示临时错误分配的值。

于 2011-01-25T20:23:34.953 回答
0

如果您真的必须在不知道正确顺序的情况下遵循插入的工作流程,然后必须稍后返回更新以设置正确的顺序,我会说您最好的选择是摆脱唯一约束,因为它会导致你的问题多于它的价值。当然,只有您知道该唯一约束对您的应用程序有多大的“价值”。

于 2011-01-25T20:36:17.290 回答