我有一个SQL Server表,我存储发票我们称之为发票。我需要为发票实现连续的自动编号(不是不连续的自动同一性)。此外,我应该同时处理并发问题,例如用户A和用户B发票,但两张发票不应该具有相同的数字(显然)。
T-SQL中理想的实现方法是什么?
答案 0 :(得分:2)
IDENTITY列。
如果您需要一个字母数字的发票号码,我建议您使用所需的格式更新您的问题。
如果删除记录,在INSERT期间遇到错误,将包含INSERT的事务回滚到表中,或者种子由相关的dbcc命令更新,则只会出现间隙。
如果你真的必须重复使用差距(我当然不会对发票这样的事情这样做,例如,在您的示例发票#32中会有更晚的日期,然后发票#190 ......):那么你可以,在可序列化的事务中,找到最低的空闲值,设置标识插入,插入具有该Id值的行,然后设置标识插入并提交事务。
像这样(未经测试):
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SET IDENTITY_INSERT dbo.myTable ON
DECLARE @minId int = -1
;WITH cterows(Id, rownum)
AS
(
SELECT Id, row_number() OVER(ORDER BY Id ASC) AS rownum
)
SELECT @minId = MIN(rownum) FROM cterows
WHERE Id <> rownum
IF (@minId IS NOT NULL AND @minId <> -1)
BEGIN
-- found a gap
-- Insert at @minId
END
ELSE
BEGIN
-- No gap, INSERT as normal
END
SET IDENTITY_INSERT dbo.myTable OFF;
COMMIT
答案 1 :(得分:2)
我们做类似事情的一种方法是创建一个名为useID
的表,其中只有一列名为[ID]
。我们使用Integer数据类型。该表也只有一行。更多相关内容。
现在,每次我们需要记录SELECT
来自useID
的事件并使用此[ID]
值运行我们的事务以用于跟踪目的。在我们SELECT
编辑[ID]
之后,我们将useID
中的值增加1(或者我们需要的系统)。通过这种方式,我们可以保持唯一且连续的[ID]
值。我们可以从[ID]
值的目标中删除,而不会影响新[ID]
值的顺序。这方面的表现非常好,因为我们每晚运行大约1000万次交易,我们确实每3个月左右重置一次起始价值,因为我们没有让物品“保持”那么久。
答案 2 :(得分:1)
如果没有必要继续这些数字,您可以创建随机数,但如果它应该继续,您可以创建该列IDENTITY
colunm
选中此post以创建随机数
答案 3 :(得分:0)
您可以为字母数字发票编号设置SQL Varchar
列,在此处您需要生成唯一的发票否,或者可以使用IDENTITY
列。