【发布时间】:2016-08-25 21:56:26
【问题描述】:
免责声明:此更改通常对正确规范化的数据库没有用处,但我有商业原因。
我有一个带有数值主键的数据表。此键在多个其他表中用作外键引用。还有一列数值可以更新以反映所需的行顺序。 order 和 PK 列包含相同的数字,但按任一列排序表会打乱另一列。
我要做的是更新主键以遵循与 order 列相同的顺序,但 SSMS 给我错误“违反 PRIMARY KEY 约束'PK_Constraint'。无法在对象'tbl 中插入重复键'。重复的键值是
我的更新语句如下所示:
update tbl set tbl.key = tbl.order where tbl.key <> tbl.order
我已经知道如何更新其他表中的外键引用,所以我只需要知道在这种情况下如何更新键。
【问题讨论】:
-
SELECT COUNT(*), COUNT(DISTINCT [key]), COUNT(DISTINCT [Order]) FROM tbl返回什么?它应该都是相同的数字。如果内部系统主键编号与外部最终用户排序属性不匹配,您为什么要关心?主键仅供内部系统使用 -
在我的例子中,我得到了
64, 64, 64作为结果。将主键与排序属性保持相同的顺序对于维护将使用此键构建的其他表中可能存在的数千行数据非常有用。我正在努力避免未来的问题。 -
我从数据库角度的建议:单独的排序属性是个好主意。一个坏主意是让两列具有相同的值,并且将真实世界的值附加到主键通常是不好的。我不确定您设想的未来问题是什么,但我建议您通过这样做来增加它们。抱歉,我对您的原始问题没有任何直接的想法,除非可以尝试不使用
WHERE -
此表定义事件中的步骤。还有另一个表定义了子步骤。两者都有一个内部序列 ID 和一个订单字段。子步骤表有一个对步骤表的 PK 的 FK 引用,作为其自己的 PK 的一部分。然后有另一个表跟踪事件的各个实例,每个实例仅在每个步骤/子步骤完成时添加行。如果每个表的 PK 都是有序的,则无需连接即可更轻松地查看每个实例的步骤/子步骤的顺序。配置设置一次,然后在事件开始发生后不会更改。
-
通过“无需连接”语句,一切都变得清晰起来。在规范化的数据库中,连接是一件好的事情,而不是一件坏事。也许创建一个视图可能会让您更轻松。出于性能原因或代码复杂性原因,您想避免连接吗?无论如何,我重申 - 从数据库的角度来看,你正在做的是一个非常糟糕的主意。
标签: sql-server tsql sql-update constraints primary-key