我希望能够生成随机&给定客户端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;
答案 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