T-SQL自动增量标识?

时间:2016-07-24 13:34:20

标签: sql-server tsql

我有一个SQL Server表定义为

CREATE TABLE [dbo].[Products] 
(
    [ProductId]   INT            IDENTITY (1, 1) NOT NULL,
    [Name]        NVARCHAR (50)  NOT NULL,
    [Description] NVARCHAR (400) NOT NULL,
    [Category]    NVARCHAR (50)  NOT NULL,
    [Price]       DECIMAL (18)   NOT NULL,
    PRIMARY KEY CLUSTERED ([ProductId] ASC)
);

现在我的问题是我之前在表格中存储了7个项目,ID依次从1到7开始,当我在表格中添加新产品时,ID会自动获得一个随机值,如1016,然后是另一个新项目item它获得值1017,依此类推。如何设置ID值以便自动检测上次存储的ID并自动在该值中递增1?

3 个答案:

答案 0 :(得分:2)

您的标识列生成的值应该无关紧要。

如果您的代码或应用程序依赖于从Identity列生成的值,那么您应该真正修复该逻辑。

根据MSDN标识值保证是增量和顺序的,但不能保证它们是否是连续值。特别是在SQL Server 2012中,它往往会有大幅度的跳跃,例如100到1000。

无论如何,要将Identity列重新设置为下一个可用的最高值,您可以执行以下操作。

-- Reseed to any lowest value say 0
DBCC CHECKIDENT ('[dbo].[Products]', RESEED , 0)
GO

-- Execute the same command but this time without any seed value 
DBCC CHECKIDENT ('[dbo].[Products]', RESEED)
GO

这会将您的标识列重新设置为标识列中的下一个最高可用值。

答案 1 :(得分:1)

您可以像这样重置身份种子:

DECLARE @cmd VARCHAR(MAX)
SELECT 'DBCC CHECKIDENT (''[dbo].[Products]'', RESEED, '+(CAST(MAX(id)+1 AS    VARCHAR(MAX)))+');' FROM [dbo].[Products]
-- PRINT @cmd
EXEC(@cmd)

你必须考虑如果你需要一个没有任何漏洞的清晰的id序列,IDENTITY将无法给你这个。如果插入行的事务将被回滚,那么IDENTITY将保持递增并且将出现新的孔。

答案 2 :(得分:1)

我对您创建表格的方式以及我对您的要求的理解有两个问题:

  1. 如果您需要连续递增没有间隙的行,则不应使用标识列。它并不保证。并试图重新选择它以填补空白是一个坏主意。最好问你自己,你真的需要它是顺序的。如果答案为是,那么您必须以编程方式在处理此表的INSERT的存储过程中实现它。我个人没有看到原因。另一个需要考虑的重要事项是,如果使用ID列将此表引用到其他表中。

  2. 您正在使用ID列和PK列,我没有看到在自然列上创建的任何其他唯一索引。因此,SQL Server不会阻止您插入两个或多个具有相同名称的产品(实际上该表中的每个列都相同)具有不同的ID。你被迫以编程方式处理这个问题。如果你依赖这个表每个产品有一行,那么模式本身并不能阻止任何人插入重复项。一个简单的解决方法是在业务键上创建唯一索引,使行唯一(名称+类别)。