使用唯一约束更新数据库记录
给定以下简单的表结构 (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,但我对严格的数据库解决方案持开放态度。
Given the following simple table structure (SQL Server 2008), I want to be able to maintain uniqueness of my numerical sequence column, but I want to be able to update that value for any given record(s).
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)
);
My interface allows me to jumble up the order of the items and I will know prior to doing the update which non-overlapping sequence they should all be in, but how do I perform the update without being confronted with a violation of the unique constraint?
For instance, say I have these records:
ID TITLE SEQUENCE
1 APPLE 1
2 BANANA 2
3 CHERRY 3
And I want to update their sequence numbers to the following:
ID TITLE SEQUENCE
1 APPLE 3
2 BANANA 1
3 CHERRY 2
But really I could be dealing with a couple dozen items. The sequence numbers must not overlap. I've thought about trying to use triggers or temporarily disabling the constraint, but that would seem to create more issues. I am using C# and LINQ-to-SQL, but am open to strictly database solutions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
最明显的方法是作为一批写入。在内部,SQL 将推迟约束检查,因此中间唯一性是无关紧要的。
逐行写入没有意义,并且会导致您遇到的问题。
您可以将其更改为写入临时表,然后最后“刷新”结果,甚至首先检查临时表的唯一性。
The obvious way is to write as one batch. Internally, SQL will defer the constraint checks so intermediate uniqueness is irrelevant.
Writing row by row does not make sense and causes the problem you have.
You can change this to write into a temp table, and then "flush" the results at the end, even check uniqueness over the temp table first.
您可以为它们指定正确值的负,然后在发生所有更新后,在设置
SEQUENCE = -SEQUENCE
的位置进行最终更新。它不是非常有效,但既然你说你只有几十件物品,我怀疑影响会很明显。我还假设您可以使用负数作为“神奇值”来指示暂时错误分配的值。
You could assign them the negative of their correct value, then after all updates have occurred, do a final update where you set
SEQUENCE = -SEQUENCE
.It is not very efficient, but since you say you only have a couple dozen items, I doubt the impact would be noticeable. I am also assuming that you can use negative numbers as "magic values" to indicate temporarily mis-assigned values.
如果您确实必须遵循在不知道正确顺序的情况下插入的工作流程,然后必须稍后返回更新以设置正确的顺序,我想说您最好的选择是摆脱唯一约束,因为它会导致你的问题比它的价值还多。当然,只有您知道该独特约束对您的应用程序有多大“价值”。
If you really have to follow that workflow of inserting without knowing the right order and then having to come back with an update later to set the right order, I'd say your best option is to get rid of the unique constraint because it is causing you more problems than it is worth. Of course, only you know how much that unique constraint is "worth" to your application.