为每个客户端ID生成随机代码

时间:2015-04-22 09:51:19

标签: sql-server sql-server-2014

我希望能够生成随机&给定客户端ID的唯一代码给定次数。我在几乎下面的代码完美地实现了这个目标,我只是说因为对RAND()函数的调用没有更新,所以值是相同的。我想你可以说代码无法实现这个目标。

代码必须是2个由4个数字组成的数字,用连字符分隔,例如0123-4567。我需要代码以零开头的可能性,并且只能包含分隔符以外的数值。

您可能需要了解的其他事项是:客户端ID是唯一标识符。 FriendlyName和FriendlyKey值必须是唯一的。代码通常将以50个批量生成。必须包含此代码的随机元素,以尝试防止对有效代码进行任何猜测。每个代码都有自己的主键(uniqueidentifier)。

据我所知,随着此过程的成熟,生成重复代码的可能性会增加,但鉴于代码是根据客户端ID生成的,每个客户端有1亿种组合(0000-0000 - 9999-9999)可用就本练习而言,这种可能性不是考虑因素。此外,检查现有数据集所需的时间将会增加,但为了本练习的目的,可以安全地忽略此考虑因素。

感谢阅读。希望有人可以提供帮助。

CREATE PROCEDURE dbo.GenerateAccessCodeForClient
@clientID uniqueidentifier,
@total int

as

DECLARE @numCodes INT = @total;
DECLARE @startNum INT = 1;
DECLARE @nums TABLE(n NVARCHAR(9) NOT NULL);
DECLARE @results TABLE(Code NVARCHAR(9) NOT NULL, ID UNIQUEIDENTIFIER NOT NULL, CLIENTID UNIQUEIDENTIFIER NOT NULL);

INSERT INTO @nums
SELECT TOP (@numCodes) RIGHT('0' + CAST(ROW_NUMBER() OVER (ORDER BY s1.[object_id]) + (@startNum - 1) AS NVARCHAR), 9) n
FROM sys.all_objects s1
          CROSS JOIN sys.all_objects s2;

INSERT [AccessCodes]([PrimaryKey], [Code], [FriendlyKey], [FriendlyName], [AdditionalInfo], [CreatedDate], [ModifiedDate], [CreatedByID], [ModifiedByID], [ClientID])
OUTPUT Inserted.Code, Inserted.PrimaryKey, Inserted.ClientID
INTO @results
select NEWID(), 
    concat(LEFT(SUBSTRING (RTRIM(RAND()) + SUBSTRING(RTRIM(RAND()),3,11), 3,11),4) , '-', LEFT(SUBSTRING (RTRIM(RAND()) + SUBSTRING(RTRIM(RAND()),3,11), 3,11),4)), 
     n, 
     'fName' + n, 
     'addInfo' + n, 
     getdate(), 
     getdate(), 
     'ffffffff-ffff-ffff-ffff-ffffffffffff',
     'ffffffff-ffff-ffff-ffff-ffffffffffff',
     'ffffffff-ffff-ffff-ffff-ffffffffffff'
FROM @nums;

SELECT Code, ID, CLIENTID
FROM @results
ORDER BY Code DESC;

2 个答案:

答案 0 :(得分:1)

试试这个:

SELECT CONCAT (
        LEFT(ABS(CAST(CAST(NEWID() AS VARBINARY) AS BIGINT)), 4)
        ,'-'
        ,RIGHT(ABS(CAST(CAST(NEWID() AS VARBINARY) AS BIGINT)), 4)
        ) AS [RandomCode]

如果您希望第一个随机整数始终为0.您可以这样做:

SELECT CONCAT (
    0
    ,LEFT(ABS(CAST(CAST(NEWID() AS VARBINARY) AS BIGINT)), 3)
    ,'-'
    ,RIGHT(ABS(CAST(CAST(NEWID() AS VARBINARY) AS BIGINT)), 4)
    ) AS [RandomCode]

答案 1 :(得分:0)

想用我自己的调整修改Rookie13的答案。尽管对于这种情况,性能可能不是一个大问题,但是下面的代码执行的操作更少(例如,仅调用一次NewID()),并且仅使用BIGINT的最后8位作为随机数。

;WITH CTE AS 
( SELECT RIGHT(CAST(CAST(NEWID() AS VARBINARY) AS BIGINT),8) AS rndm )
SELECT CONCAT(LEFT(rndm,4),'-',RIGHT(rndm,4)) 
FROM CTE