如何避免SQL Server中的重复值

如何避免SQL Server中的重复值,sql,sql-server-2008,duplicates,Sql,Sql Server 2008,Duplicates,我有近10台代币机,客户从表代币中获取代币号码。我正在使用存储过程访问此表并对其进行更新 Id Name TokenFrom TokenTo LastUsedToken ---------------------------------------------------- 1 Token 551 999 562 我注意到,在高峰时间,很多客户都会收到重复的号码。可能出现这个问题是因为10位客户同时/小时/秒获得代

我有近10台代币机,客户从表
代币
中获取代币号码。我正在使用存储过程访问此表并对其进行更新

Id    Name       TokenFrom   TokenTo   LastUsedToken
----------------------------------------------------
1     Token         551        999         562
我注意到,在高峰时间,很多客户都会收到重复的号码。可能出现这个问题是因为10位客户同时/小时/秒获得代币

这是
issuedToken
表格

Id  PosId   Barcode        Date                      Status  Number isTaken 
1   2       6282019214317  2016-10-20 09:41:45.020    1      366        1
2   2       6282019215918  2016-10-20 09:42:15.020    1         367     1
3   2       6282019225016  2016-10-20 09:42:45.020    1         368     1
4   3       6282019230812  2016-10-20 09:42:55.020    1         369     1
甚至有时两台出纳机上也会出现相同的号码。我正在使用此
Update
语句获取并更新POS上的下一个令牌号

UPDATE POS 
SET tNo = (SELECT TOP 1 NUMBER 
           FROM Tickets 
           WHERE STATUS = 1 
             AND isTaken = 1 
             AND PosId = (SELECT CGROUP 
                          FROM POS 
                          WHERE NAME='ABC')) 
WHERE NAME = 'ABC'
我在一个组中有3-3个POS,这就是为什么选择
cGroup
,在表中它是
PosId

在这个问题中,我曾经问过与这个问题相关的问题,有人帮助我编写一个存储过程,以便轻松访问令牌号

但我仍然有重复问题。谁能告诉我避免重复的最佳方法是什么


假设您拥有SQL Server 2012(请澄清)

不是一个完整的答案,但如果你愿意,我可以扩展

首先创建一个序列(只运行一次):

现在从中获取下一个序列(可以随时运行):

此方法不能将相同的数字分配给两个不同的请求,因此不会得到重复的数字。当达到350时,它将自动环绕。您可以为其他分组创建和使用序列。比其他解决方案简单得多,而且100%可靠


我需要再次建议不要为特定组创建幻数范围。

这假设您有SQL Server 2012(请澄清)

不是一个完整的答案,但如果你愿意,我可以扩展

首先创建一个序列(只运行一次):

现在从中获取下一个序列(可以随时运行):

此方法不能将相同的数字分配给两个不同的请求,因此不会得到重复的数字。当达到350时,它将自动环绕。您可以为其他分组创建和使用序列。比其他解决方案简单得多,而且100%可靠


我需要再次建议不要为特定的组创建幻数范围。

这里有一个在SQL 2008中有效的方法,但它不考虑组,不重置,并且有一个不同的条形码公式

这是颁发的令牌表。在此处插入记录“保留”令牌号:

CREATE TABLE [dbo].[issuedToken2](
    [Token] [int] IDENTITY(1,1) NOT NULL,
    [Barcode]  AS (((6820000000.)+[Token])*(100)+[PosID]),
    [GenerationDate] [smalldatetime] NOT NULL,
    [PosID] [int] NOT NULL
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[issuedToken2] 
    ADD  CONSTRAINT [DF_issuedToken_GenerationDate]  
    DEFAULT (getdate()) FOR [GenerationDate]
GO
这是一个可用于获取令牌号的存储过程。您可以让100个系统同时调用此功能,它们将获得不同的号码:

CREATE PROC [dbo].[pGetToken]
@PosID INT
AS
BEGIN
SET NOCOUNT ON

insert into issuedToken2 (PosID) 
VALUES(@PosID)

RETURN scope_identity()
END
GO
这就是您使用它的方式:使用posid调用存储的proc(在本例中为7)以保留令牌号,然后使用它获取条形码:

DECLARE @Token INT

EXEC @Token = pGetToken 7

SELECT @Token, [Barcode]
FROM issuedToken2
WHERE Token=@Token

基本上,这是通过使用
标识
——一个递增的数字来实现的。我知道您现有的系统不能像这样工作,但您没有解释为什么需要这样做。

这里有一个在SQL 2008中可以工作的东西,但不考虑分组,不重置,并且有一个不同的条形码公式

这是颁发的令牌表。在此处插入记录“保留”令牌号:

CREATE TABLE [dbo].[issuedToken2](
    [Token] [int] IDENTITY(1,1) NOT NULL,
    [Barcode]  AS (((6820000000.)+[Token])*(100)+[PosID]),
    [GenerationDate] [smalldatetime] NOT NULL,
    [PosID] [int] NOT NULL
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[issuedToken2] 
    ADD  CONSTRAINT [DF_issuedToken_GenerationDate]  
    DEFAULT (getdate()) FOR [GenerationDate]
GO
这是一个可用于获取令牌号的存储过程。您可以让100个系统同时调用此功能,它们将获得不同的号码:

CREATE PROC [dbo].[pGetToken]
@PosID INT
AS
BEGIN
SET NOCOUNT ON

insert into issuedToken2 (PosID) 
VALUES(@PosID)

RETURN scope_identity()
END
GO
这就是您使用它的方式:使用posid调用存储的proc(在本例中为7)以保留令牌号,然后使用它获取条形码:

DECLARE @Token INT

EXEC @Token = pGetToken 7

SELECT @Token, [Barcode]
FROM issuedToken2
WHERE Token=@Token

基本上,这是通过使用
标识
——一个递增的数字来实现的。我知道您现有的系统不能这样工作,但您还没有解释为什么需要这样做。

我通过更改正在访问下一个数字的存储过程获得了解决方案。现在的逻辑是锁定
Token
表并获取下一个数字。现在我只得到唯一的数字


谢谢大家的友好回应

通过更改正在访问下一个数字的存储过程,我得到了解决方案。现在的逻辑是锁定
Token
表并获取下一个数字。现在我只得到唯一的数字


谢谢大家的友好回应

@RyanVincent,客户在代币系统中输入10位国家ID,并获得代币号码代币只是一个递增的数字吗?(请解释)。使用
序列
标识
(插入记录,然后使用
范围标识
)。任何其他复杂的MAX或手动锁定方法都会给您带来问题。@RyanVincent,顺便说一句,我在发布时也会生成一个13位的唯一条形码ticket@Nick.McDermaid,是的,它只是递增的数字。除此之外,我建议你使用一个身份或序列,但首先我必须说服你,为特殊目的设置一个特殊的票号范围是个坏主意。为什么女性需要1-50岁?如果你一天有50多位女士会怎么样。不管怎样,您是否链接到了另一个问题,因为这是您实现它的方式?那肯定会给你重复的tokens@RyanVincent,客户在代币系统中输入10位国家ID并获得代币号码代币只是一个递增的号码吗?(请解释)。使用
序列
标识
(插入记录,然后使用
范围标识
)。任何其他复杂的MAX或手动锁定方法都会给您带来问题。@RyanVincent,顺便说一句,我在发布时也会生成一个13位的唯一条形码ticket@Nick.McDermaid,是的,它只是递增的数字。除此之外,我建议你使用一个身份或序列,但首先我必须说服你,为特殊目的设置一个特殊的票号范围是个坏主意。为什么女性需要1-50岁?如果你一天有50多位女士会怎么样。不管怎样,您是否链接到了另一个问题,因为这是您实现它的方式?这肯定会给你重复的标记我有Sql Server 2008 R22,甚至2