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