**更新(5/18/2017)**
我发现问题没有我想象的那么大。这仅在部署架构后发生,并且在初始阶段期间迁移错误。只有在新数据库有新的或修改时,才需要部署模式。然后,一旦迁移工具开始,它必须成功填充整个数据库(大约需要20分钟),因此错误数量*完成所需的时间=修复所有错误的总时间,这可能需要几个小时。然而,如果发生这种情况,它会有点令人不安。如果迁移成功,并且没有对架构进行任何修改,那么下面的场景就不会有麻烦了。这些修改不会经常发生,可能每月一次或两次。尽管如此,我仍然对其他类型的解决方案感兴趣。但是这个问题需要花费大量时间来了解最新情况。
**原帖(2017年5月17日)**
我已经回顾了以下相关的Stack Overflow问题,但没有人回答我正在经历的事情。
Why setting current identity value is not working for me in SQL Server 2008 R2?
Cannot truncate table because it is being referenced by a FOREIGN KEY constraint?
返回故事
我的任务是迁移数据库,包括重组表,确保它具有数据完整性,并简化模式。此迁移由c#应用程序执行,该应用程序调用存储过程,添加业务逻辑等。每天早上5点,有一个任务调度程序清除除审计表之外的所有数据,并检索所有刷新的数据(如果是原始数据)数据已更新)。迁移工具是幂等的,因此可以删除和重新创建数据库,并且在运行迁移工具之后,一切都恢复正常(使用刷新的数据)。此外,迁移工具首先通过引用表导入相关数据,以确保不会发生违反约束的情况,并且还会选择这些索引ID,而不是任何旧的旧ID。每个表都有IDENTITY(1,1)
为了确保刷新数据库,我必须执行DELETE FROM操作。截断表不起作用,因为会违反外键约束。所以我这样做的方法是关闭约束,从数据中删除,重新启用约束,然后重新设置值。
因此,当我的程序运行时,它会执行以下行:
sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
sp_MSForEachTable 'DELETE FROM ?'
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'"
EXEC sp_MSforeachtable 'DBCC CHECKIDENT(''?'', RESEED, 0)'
但是,如果数据库实例是全新安装,并且我运行迁移工具,并且它出错,则会出现问题,因为某些表将不会被填充。由于一些表已插入记录,而其他表没有插入记录;这意味着,如果我在我的迁移工具中再次运行上面的代码,那么插入记录的表的下一个种子值将是ID = 1,而未触及的表的种子值将为null(和第一个插入将以ID = 0开始。这是因为这会覆盖IDENTITY(1,1)。如果我要在没有插入记录的表上运行DBCC CHECKIDENT,例如
DBCC CHECKIDENT ('TABLEA', NORESEED)
您将获得以下内容:
检查身份信息:当前身份值'NULL',当前 列值'NULL'。
无论您做什么,都不能将“NULL”的标识值重新设置为任何其他数字。
这成为一个严重的问题,因为每次迁移工具运行时,我都会继续遇到外键约束违规,因为引用的表中不存在某些索引。这也有多米诺骨牌效应,如果一个表被不正确地索引(ID = 0),那么引用该表的所有表都将违反约束 - 跳过导入,这些表上的索引将是ID = 0以及下一个表我们运行迁移工具的时间。
HACK SOLUTION:
我希望所有的表都从ID = 1开始,而不是0.所以截至目前,确保运行的唯一可行方法是从干净的平板(删除并重新创建)中清除数据库,注释掉四个上面的命令代码,运行迁移工具,希望它成功填充所有表,返回代码,取消注释四个命令代码,并将工具部署到任务调度程序。
问题
有没有办法DBCC CHECKIDENT
可以返回我的c#应用程序可以识别的值,或者可能找到/忽略尚未插入的所有表,所以我只能重新插入已经插入的那些?或者我应该尝试跟踪哪些表运行,并查看迁移工具是否可以在下次运行时忽略这些表?如果是这样的话,最好的办法是什么?