在我们的某个应用中,我们从文件中读取数据并将其扩展为多个表格。如果文件的任何部分损坏,我们将暂停读取,并删除插入的任何数据。
这里的问题是我们在其中一个导入表上有一个自动增量ID,当我们删除一个问题文件时,ID会从其导入后的值继续,而不是它的导入前值。
换句话说......
我们“丢失”了100条记录的范围。是否有“自动减量”等同于自动增量?
答案 0 :(得分:3)
Autonumbers对你来说不应该那么有意义。他们的保证是他们不再提供独特性。如果您使用的是SQL Server DBCC CHECKIDENT
,则仍可以重新设置。
Checks the current identity value for the specified table and, if it is needed, changes the identity value. You can also use DBCC CHECKIDENT to manually set a new seed value for the identity column.
来自BOL: 以下示例将AdventureWorks数据库中Employee表中的当前标识值强制为值30。
USE AdventureWorks;
GO
DBCC CHECKIDENT ('HumanResources.Employee', RESEED, 30);
GO
我不是推荐这个,而是指出来。如果您尝试重新设定已经使用的值,DBCC CHECKIDENT
会抛出错误,在这种情况下,如果您依赖此类任务,则必须具有逻辑。
我质疑这些数字如此重要的思维过程?听起来你想要一个名为LineNumber
的额外字段增加或减少等等。但即使在这种情况下你也必须处理删除记录之后的行。因此,如果您有50行并删除第25行,则必须重新编号大于25的行:
UPDATE
MyTable
SET LineItemNumber = LineItemNumber - 1
WHERE
LineItemNumber > @LineItemNumberToBeDeleted
答案 1 :(得分:2)
删除时自动减少听起来像个坏主意。如果操作不正确,您可以开始在代码中注入更大的错误。如果ID是一个大问题,请尝试给它一个批号,并为批处理中的每个项目增加一个id。你也可以使用guids,虽然它们不是连续的。
答案 2 :(得分:2)
您可以通过执行以下操作重新设置自动增量ID:
DBCC CHECKIDENT
(
tablename
[, [NORESEED | RESEED [, newreseedvalue]]]
)
但我不建议将此作为最佳做法。您的查询应该是原子的(它提交并更新表或者如果失败则返回Rollsback(保持ID不变)。要实现原子查询,您可以使用TRANSACTION
。
BEGIN TRY
BEGIN TRANSACTION @TranName;
-- Your database logic here
COMMIT TRANSACTION @TranName;
END TRY
BEGIN CATCH
ROLLBACK TRAN @TranName;
END CATCH
GO
来源:
http://msdn.microsoft.com/en-us/library/ms188929.aspx
http://www.techrepublic.com/blog/datacenter/how-do-i-reseed-a-sql-server-identity-column/406
答案 3 :(得分:0)
根据我的经验,这部分ETL(提取变换加载)过程的最佳实践是在多个步骤中执行批量加载: