【发布时间】:2010-10-23 21:02:57
【问题描述】:
sql server 2005:我在员工表中有一个带有标识的列 empid。如果在将数据插入表时出现一些错误。标识递增。我希望只有在插入记录时标识才递增。就像我有从 1 到 5 生成 emp id,然后在第 6 条记录插入错误 ocurrs.and 在下一条记录插入标识值将是 7。我希望它是 6。
【问题讨论】:
标签: sql-server-2005 tsql transactions
sql server 2005:我在员工表中有一个带有标识的列 empid。如果在将数据插入表时出现一些错误。标识递增。我希望只有在插入记录时标识才递增。就像我有从 1 到 5 生成 emp id,然后在第 6 条记录插入错误 ocurrs.and 在下一条记录插入标识值将是 7。我希望它是 6。
【问题讨论】:
标签: sql-server-2005 tsql transactions
你为什么要这么做?
标识列应该只用作数据库的“内部管理价值”,它不应该有“商业价值”,那么为什么在该序列中存在空白很重要呢?
如果正确使用身份,那么您的软件的用户将永远不会面对具有身份值的列;您只需使用它来唯一标识一条记录。
【讨论】:
我不认为这是可以做到的。如果您希望您的身份号码完全连续,那么您可能必须自己生成它们,而不是使用 SQL 身份功能。
编辑:即使回滚失败的事务也不会使身份计数下降,这是设计使然,请参阅this other question。
【讨论】:
如果存在差距,您有什么正当的商业理由来关注?数据库没有理由关心,也没有理由要确保身份值永远不会被重用于其他东西,因为它们可能会导致数据完整性出现重大问题,例如根据旧报告查找信息等。假设您有一个报告显示上个月的订单,然后您删除其中一条记录,因为客户被重复并因此被删除。然后,您为被删除的重复客户重复使用身份字段。现在有人在上个月的报告中查找客户 12345,与该客户相关的数据属于 John Smith 而不是 Sally Jones。但是这个人不知道,因为她使用的是聚合,所以现在她有完全可以避免的不正确信息。如果她正在查找删除的客户,则该流程可能会将她重定向到删除重复数据后留下的正确客户。
【讨论】:
当您需要具有这种特定行为时,您应该使用存储过程来生成 ID。这样你就可以真正地回滚了。但请记住,当前的行为是有目的的。 当您不对保存当前或下一个 ID 值的主数据表中的 id 字段使用锁定时,事务隔离和不同的读取级别(脏读)很可能会给您带来麻烦。
【讨论】: