如何从DB表中获取下一个ID而没有IDENTITY或GUID列

Mon*_*eep 1 sql sql-server transactions

我有一个INT主键列表.我不想使用GUIDIDENTITY作为主键.

我想知道在不使用表中的IDENTITYGUID作为主键列的情况下获得下一个ID的最佳方法是什么.我不介意使用GUIDIDENTITY在表中,除非它是主键列.

我必须找到下一个可用的ID(即获取MAX ID并将其递增1),并使用:

SELECT @id=ISNULL(max(AlbumId)+1,1) FROM Albums
Run Code Online (Sandbox Code Playgroud)

但是,我想阻止其他应用程序在我执行此操作时插入到表中,以便我们没有任何问题.

注意:请勿将此问题标记为DUPLICATE.我已经完成了这个答案,无法理解它.有人会善意地向我解释他们在做什么吗?我可以使用相同的技术吗?

mar*_*c_s 6

对于SQL Server二零零零年至2008年R2,使用INT IDENTITY迄今为止最简单,最可靠的做到这一点的方式.

试图自己做这个就像重新发明轮子并带来很多可能出错的方法 - 所以为什么要这么麻烦?你需要(一)确保这个机制是并发安全的(并且只是在做SELECT MAX(ID) + 1不是安全的!),你(二)需要确保您的机构不会成为一个主要的瓶颈在系统性能,要么...

使用INT IDENTITY主键有什么问题?看起来不太合理......

对于SQL Server 2012及更高版本,您还可以考虑使用a SEQUENCE(基本上IDENTITY不是专门连接到单个表)

更新: 你在帖子中提到的其他SO问题基本上是在做一个"自己动手"的模拟SEQUENCE:

  • 一个表包含对(sequencename, currentvalue)
  • 当您为给定序列请求新值时,使用UPDATE与该OUTPUT子句结合的语句来确定新值

为什么这么复杂?这是IDENTITY安全地处理并发请求的最简单,最有效的方法(除了使用).该UPDATE声明将始终独占锁定一个行中的"序列表"的顺序,你想获得一个新ID的-从而防止任何其他交易,以获取相同的ID,并得到重复值-它返回新的ID使用OUTPUT条款回呼叫者,召集者.