Sql server SQL Server自定义标识列

Sql server SQL Server自定义标识列,sql-server,concurrency,identity,Sql Server,Concurrency,Identity,我想生成一个与产品类型相关的自定义标识列。 这个查询能否保证身份顺序并解决并发性问题。 这是一个示例查询: BEGIN TRAN INSERT INTO TBLKEY VALUES((SELECT 'A-' + CAST(MAX(CAST(ID AS INT)) + 1 AS NVARCHAR) FROM TBLKEY),'EHSAN') COMMIT 这将是一件坏事,因为无法保证同时运行的两个查询不会得到相同的MAXID值 如果使用标准标识列,还可以使用计算列,或者在返回数据时仅返回键 E

我想生成一个与产品类型相关的自定义标识列。 这个查询能否保证身份顺序并解决并发性问题。 这是一个示例查询:

BEGIN TRAN INSERT INTO TBLKEY VALUES((SELECT 'A-' + CAST(MAX(CAST(ID AS INT)) + 1 AS NVARCHAR) FROM TBLKEY),'EHSAN') COMMIT
这将是一件坏事,因为无法保证同时运行的两个查询不会得到相同的MAXID值

如果使用标准标识列,还可以使用计算列,或者在返回数据时仅返回键

Ed

试试这个:

BEGIN TRAN

INSERT INTO TBLKEY
VALUES((SELECT MAX(ID) + 1 AS NVARCHAR) FROM TBLKEY WITH (UPDLOCK)),'EHSAN')

COMMIT
选择“最大ID”时,您将获得行上的U形锁。U锁与U锁不兼容,U锁将尝试获取另一个会话,同时运行相同的查询。在给定时间只执行一个查询。ID将有序且连续,其间没有任何间隙

更好的解决方案是创建一个只用于存储当前或下一个id的额外表,并使用它而不是最大值

您可以通过执行以下操作来理解差异:

准备一张桌子

CREATE TABLE T(id int not null PRIMARY KEY CLUSTERED)
INSERT INTO T VALUES(1)
然后在间隔不到10秒的两个不同会话中逐个运行以下查询

BEGIN TRAN
DECLARE @idv int
SELECT @idv = max (id) FROM T
WAITFOR DELAY '0:0:10'
INSERT INTO T VALUES(@idv+1)
COMMIT
等待一段时间,直到两个查询都完成。观察其中一个成功,另一个失败

现在对以下查询执行相同的操作

BEGIN TRAN
DECLARE @idv int
SELECT @idv = max (id) FROM T WITH (UPDLOCK)
WAITFOR DELAY '0:0:5'
INSERT INTO T VALUES(@idv+1)
COMMIT
查看T的内容


使用DROP Table T清理T表

如果他将查询更改为FROM TBLKEY with UPDLOCK,则可以进行尝试。这样,同时运行的两个查询无法获得相同的MAXID,其中一个查询将被另一个查询阻塞。此外,我认为生成的ID不仅是升序的,而且也是连续的。这种方法的缺点是所有并行查询都是序列化的。更不用说CASTID AS INT的形式是CAST'A-XXXX',这会失败。@Ed Elliot,我不能使用标识和计算字段,因为数字的连续性与产品类型有关,比如10001 productA,20001 productB。@Blim,我知道上面的CAST有错误,但我说它只是一个示例。@Ehsan我理解它,但我想提及它以备将来参考。尝试UPDLOCK提示,您可以找到更多关于它的信息,而不是+1。尝试使用序列。@DudiKonfino,我不能使用标识或序列以及计算字段,因为数字的连续性与产品类型有关,如10001 productA,20001产品您可以从10001开始创建,步骤100001。似乎您认为您的集合需要是连续的。这是一种常见的错误信念。也就是说,除了ID空间看起来漂亮之外,你还有什么商业理由?使用SQL Server为您提供的工具,即标识列或序列值,使您的生活更加轻松。谢谢,正如您在两个不同的事务中所说,我只测试了Select语句,效果很好。如果没有UPDLOCK,它可能会工作,但它是不正确的。使用UPDLOCK,我还可以将新id放入变量中,并在Insert语句中使用它:BEGIN TRAN DECLARE@NEWID as NVARCHAR SET@NEWID=Select MAXID+1 as NVARCHAR FROM TBLKEY with向上锁定插入TBLKEYVALUES@NEWID“EHSAN”承诺对吗?非常感谢。非常有用。