在多用户环境中使用SQL生成唯一的序列号

时间:2016-08-01 07:21:27

标签: c# sql-server-2008 concurrency

我想在tbl1表中生成一些独特的顺序计数器,所以我编写了以下代码:

using (var dbConnection = CommonDA.GetDbConnection())
{
     var command = dbConnection.CreateCommand();
     dbConnection.Open();
     command.CommandText = "insert into tbl1(Counter) select Max(Counter)+1 from tbl1;";
     command.ExecuteNonQuery();
}

但有时生成的计数器是重复的(因为多个用户运行代码),是否有任何机制可以生成唯一的顺序计数器?

3 个答案:

答案 0 :(得分:1)

你可以尝试像这样使用SEQUENCE

Source

  

第1步:

     

在这一步中,我们需要创建一个样本表和一个序列   演示它。

-- This script is compatibile with SQL Server 2012 and above.
-- CREATE TABLE
USE tempdb
GO
CREATE TABLE dbo.tbl_sample
( [ID] VARCHAR(8) ,
  [Name] varchar(50)
CONSTRAINT PK_Employee_EmployeeID
PRIMARY KEY CLUSTERED ([ID] ASC) )
GO

--CREATE SEQUENCE
USE tempdb
GO
CREATE SEQUENCE dbo.Sample_Seq AS
INT START WITH 1
INCREMENT BY 1 ;
GO
     

第2步:

     

在此步骤中,我们需要为[ID]列创建默认值   上表,[ID]列的默认值应该是   SEQUENCE并添加一个自定义脚本以使其成为varchar。

     

以下是脚本。

-- This script is compatibile with SQL Server 2012 and above.
-- CREATE DEFAULT VALUE OF SEQUENCE
USE tempdb
GO
ALTER TABLE dbo.tbl_sample
ADD CONSTRAINT Const_Sample_Seq
DEFAULT FORMAT((NEXT VALUE FOR dbo.Sample_Seq),'CUS0000#') FOR [ID];
GO
     

第3步:

     

允许在表格中插入少量记录。

-- This script is compatibile with SQL Server 2012 and above.
-- Insert records into the table
USE tempdb
GO
INSERT INTO dbo.tbl_sample ([Name])
VALUES ('Imran'),('Bob'),('Sandra')
GO
     

第4步:

     

插入数据后,您可以浏览表格并查看   [ID]列数据,它只是一个数字或varchar。

--Browse Table
USE tempdb
GO
SELECT * FROM tbl_sample
GO
--OUTPUT

答案 1 :(得分:0)

在SQL Server 2008中没有sequence对象,但这并不意味着您无法模仿其中一个,包括序列对象的所有选项,除了兑现。 但是,你必须考虑到序列中可能存在间隙的事实(即1,2,5,6,8 ......)

要做到这一点,首先要创建一个包含单个列的表,该表指定为identity

CREATE TABLE tblSequence
(
    Number int identity(1, 1)
)

然后,创建一个存储过程,它将为您提供下一个数字:

CREATE PROCEDURE stp_NextSequenceNumber
(
    @NextNumber int output
)
AS
BEGIN
    INSERT INTO tblSequence DEFAULT VALUES
    SELECT @NextNumber = SCOPE_IDENTITY()
END
GO

现在,您只需执行存储过程即可完成下一个数字:

DECLARE @NextNumber int
EXEC stp_NextSequenceNumber @NextNumber output

还可以使用truncate table进一步开发该过程来处理序列的回收,这将删除表中的所有值并将标识列重置为它的种子:< / p>

CREATE PROCEDURE stp_NextSequenceNumber
(
    @NextNumber int output
)
AS
BEGIN

    DECLARE @CurrentNumber int
    SELECT @CurrentNumber = MAX(Number)
    FROM tblSequence

    IF @CurrentNumber >= 10 -- In this example, 10 is the max value of the sequence
        TRUNCATE TABLE tblSequence 

    INSERT INTO tblSequence DEFAULT VALUES
    SELECT @NextNumber = SCOPE_IDENTITY()

END
GO

答案 2 :(得分:-1)

是。您可以通过SQL Server使用NEWSEQUENTIALID。它保证在空间和时间上都是独一无二的。