如何避免SQL Server

时间:2016-10-21 00:13:34

标签: sql sql-server-2008 duplicates

我有近10台令牌机,客户从表Token获取令牌号码。我正在使用存储过程来访问此表并进行更新

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

我之前在这个问题中提出了与此问题相关的问题,有人帮我编写了一个存储过程,可以轻松访问令牌号码。

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

What is Best Approach for Auto Increament

3 个答案:

答案 0 :(得分:2)

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

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

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

create sequence CustomerCare 
    as integer
    start with 51
    increment by 1
    minvalue 51
    maxvalue 350
    cycle;

现在从中获取下一个序列(根据需要随时运行):

select next value for CustomerCare

此方法无法将相同的号码分发给两个不同的请求,因此您不会获得重复项。它会在到达350时自动换行。您可以为其他分组创建和使用序列。比其他解决方案简单得多,100%可靠。

我需要建议不要为特定群体创建幻数范围。

答案 1 :(得分:1)

这是在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调用存储过程(在这个例子中为7)来保留令牌号,然后用它来获取条码:

DECLARE @Token INT

EXEC @Token = pGetToken 7

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

基本上,这可以通过使用identity - 递增数字来实现。我知道你现有的系统并不像这样工作,但你还没有解释它为什么需要。

答案 2 :(得分:0)

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

感谢大家的回复。