我想生成与产品类型相关的自定义标识列。 此查询可以保证身份的顺序并解决并发问题。 这是一个示例查询:
BEGIN TRAN INSERT INTO TBLKEY VALUES((SELECT 'A-' + CAST(MAX(CAST(ID AS INT)) + 1 AS NVARCHAR) FROM TBLKEY),'EHSAN') COMMIT
答案 0 :(得分:0)
这样做是件坏事,因为无法保证同时运行的两个查询不会使MAX(ID)成为相同的值。
如果您使用标准标识列,则还可以使用计算列来使用该列,或者在返回数据时返回密钥。
版
答案 1 :(得分:0)
试试这个:
BEGIN TRAN
INSERT INTO TBLKEY
VALUES((SELECT MAX(ID) + 1 AS NVARCHAR) FROM TBLKEY WITH (UPDLOCK)),'EHSAN')
COMMIT
选择最大ID时,您会在该行上获得U锁定。 U锁与U锁不兼容,U锁将尝试使用同时运行的同一查询获取另一个会话。在给定时间只执行一个查询。 ids将按顺序连续,没有任何间隙。
更好的解决方案是创建一个专用于存储当前或下一个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