【发布时间】:2021-12-10 07:31:40
【问题描述】:
在将我的一个 SQL SERVER 数据库中的所有表重建到一个新数据库后,我未能将许多表的“ID”列设置为 IDENTITY 和 PRIMARY KEY。他们中的大多数都有数据。
我发现了这个 T-SQL,并且已经成功地为几个表实现了它。新的/替换的 ID 列包含与前一列相同的值(仅仅是因为它们来自我导入的表中的自动递增列),并且我现有的存储过程仍然有效。
Alter Table ExistingTable
Add NewID Int Identity(1, 1)
Go
Alter Table ExistingTable Drop Column ID
Go
Exec sp_rename 'ExistingTable.NewID', 'ID', 'Column'
--Then open the table in Design View, and set the new/replaced column as the PRIMARY KEY
--I understand that I could set the PK when I create the new IDENTITY column
新的/替换的 ID 列现在是表中的最后一列,到目前为止,我还没有遇到调用存储过程的 ASP.Net/C# 数据访问对象的问题。
如前所述,这些表中的每一个都没有设置 PRIMARY KEY(也没有 FOREIGN KEY)。考虑到这一点,我是否应该采取任何其他步骤来确保数据库的完整性?
我遇到了this SO 帖子,它建议我应该运行“ALTER TABLE REBUILD”语句,但由于没有设置 PK,我真的需要这样做吗?
最终,我只是想确保我不会制造直到游戏后期才会出现的问题,并确保我正在实施的方法合理、合乎逻辑并确保数据完整性。
我想用正确的 PK/IDENTITY 列来 DROP/RECREATE 表可能是一个更好的选择,我可以编写一些 T-SQL 将现有数据转储到 TEMP 表中,然后删除/重新创建,然后重新- 使用 TEMP 表中的数据填充新表。我特别避免了这个选项,因为它看起来更具侵略性,而且我不完全理解它对依赖于这些表的存储过程/函数等意味着什么。
这是我执行过此操作的其中一张表的示例。可以看到NewID的值和原来的ID是一样的。enter image description here
【问题讨论】:
-
你到底在问什么?您的标题询问如何将
IDENTITY列添加到您的表中,但问题表明您已经知道如何做到这一点并且担心数据库的完整性。从技术上讲,您的数据库的完整性很少,因为没有主键 (PK),因此也没有外键 (FK)。但是,当您添加新的IDENTITY列时,分配的值将是任意的;它们与现有的非 PK "ID" 列没有任何关系。因此,如果您确实有任何“伪”关系,而不使用 FK,那么它现在不太可能匹配。 -
对,所以您已经有一个包含可用主键值的列,并且可能其他表及其记录已经链接回它)即您有一个 ID 为 123 的地址记录和一个人员 ID 111,其 AddressId 为 123)。为什么不将此列设置为 PK,将其设置为标识并从已经存在的值的 max+1 开始呢?制作另一列将是一件令人头疼的事情,因为它会得到一堆不同的 auto inc 值,然后您需要使用旧引用将子记录连接起来并插入新引用......这一切听起来都很乏味!
-
公平点。是的,我知道怎么做。问题是..我正在实施的方法是否足够合理以确保完整性?我知道它目前没有完整性;原来的表确实有 PK 的。我只是在导入这个新数据库时没有设置它们。一旦我设置了这些 PK,我以前这样做的方法是否值得确保这种完整性?此外,现有的非 PK、非 IDENTITY ID 是连续的,并且与我已经执行过的每个表完全匹配。我希望其他表的结果相同。但我明白你的意思。
-
不太可能,@JeffKing,这些值将被完全任意分配。没有人保证,没有人,他们会是一样的。当您似乎没有 PK 并且可能没有聚集索引时尤其如此。
-
这能回答你的问题吗? Adding an identity to an existing column 特别是这个答案stackoverflow.com/a/1730868/14868997
标签: sql-server primary-key alter-table