为SQL Server中的表中的用户生成随机令牌(唯一ID)

时间:2017-12-08 20:45:13

标签: sql sql-server tsql

我想在sql server中创建一个表并用数据填充(人们的信息)。目标是让每个人在第一行中获得一个唯一ID,该ID必须以固定字母GM开头,后跟A-Z2-9数字,名字的首字母,姓氏的首字母和A-Z2-9

2 个答案:

答案 0 :(得分:1)

注意:根据您要求的逻辑,我不认为您可以生成唯一值而不检查表格是否包含生成的值,唯一的方法是使用{{1生成GUID的函数,否则我认为总有重复风险

我不知道这是否是最好的方法,但我可以说它提供了预期的输出。您可以创建此函数并使用它来生成标识符:

NEWID()

您可以将其用作以下

ALTER FUNCTION dbo.CreateIdentifier
(
    -- Add the parameters for the function here
    @Firstname varchar(255),
    @Lastname varchar(255),
    @random1 decimal(18,10) ,
    @random2 decimal(18,10)
)
RETURNS varchar(10)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @S VARCHAR(10)
    DECLARE @S1 VARCHAR(1)
    DECLARE @S2 VARCHAR(1)
    DECLARE @len INT
    DECLARE @Random1Fixed INT
    DECLARE @Random2Fixed INT

    declare @alphabet varchar(36) = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ23456789'



    SET @alphabet = REPLACE(@alphabet,LEFT(@Lastname,1),'')
    SET @alphabet = REPLACE(@alphabet,LEFT(@Firstname,1),'')

    SELECT @len = len(@alphabet)
    SET @Random1Fixed = ROUND(((@len - 1 -1) * @random1 + 1), 0)
    SET @Random2Fixed = ROUND(((@len - 1 -1) * @random2 + 1), 0)


    SET @S1 = substring(@alphabet, convert(int, @Random1Fixed ), 1)
    SET @S2 = substring(@alphabet, convert(int, @Random2Fixed), 1)

    SET @S = 'GM' + @S1 + LEFT(@Firstname,1) + LEFT(@Lastname,1) + @S2
    RETURN @S

END

我传递SELECT dbo.CreateIdentifier('John','Wills',RAND(),RAND()) 作为参数,因为它不能在函数

中使用

答案 1 :(得分:1)

你的问题有一些含糊之处,但希望通过阅读本文,你将能够填补空白。

您可能想问的一个问题是,您是否真的想要符合您提供的ID限制。使用标识列可能更有意义(参见:https://docs.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property)。

确切的语法取决于您正在使用的SQL的哪种方言。看看这个:https://www.w3schools.com/sql/sql_autoincrement.asp

对于MS SQL服务器,它看起来像这样:

create table User (
   [UserID] int IDENTITY(1,1) PRIMARY KEY,
   [FirstName] varchar(50) not null,
   [LastName] varchar(50) not null
)

我们假设你用几个条目填充了这个表。如果对于某些任意要求,你需要" GM"在前面和最后用户的首字母缩写中,您可以执行以下操作:

select 'GM'+UserID+'substring(FirstName,0,1)+substring(LastName,0,1) from User

要更直接地回答您的问题,您似乎要求每个用户都拥有一个类似于GM[A-Z or 2-9][FirstInitial][LastInitial][A-Z or 2-9)]

的ID

这种设置会给你带来很多麻烦,但它确实可行。请注意,据我了解你的要求,在GM之后只有一个A-Z / 0-9字符,而在首字母之后只有一个字符会给你一个非常有限的可能的唯一ID#。

你没有给出最大ID字符长度,所以我假设整个长度固定为6个字符(" G"," M"," ; AZ / 2-9"" F"" L"" AZ / 2-9&#34)。如果我误解你,那肯定会改变答案,但希望这仍然有用。

您可以创建一个User表和一个包含可能的字符的表,如下所示:

create table UserTable  (
    ID varchar(50),
    FirstName varchar(50),
    LastName varchar(50)
)

create table PChars (
    Possibility varchar(1)
)

insert into PChars (Possibility) values
('A'),('B'),('C'),('D'),('E'),('F'),('G'),('H'),('I'),('J'),('K'),('L'),('M'),('N'),('O'),('P'),('Q'),('R'),('S'),('T'),('U'),('V'),('W'),('X'),('Y'),('Z'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9')

然后你可以反复运行以下内容,注意John和Jane永远不会有相同的ID,即使它们具有相同的首字母。 while条款禁止它。

另请注意,最终会破裂。如果表中有足够多的具有相同首字母的人,则while子句可能会变成无限循环。 这就是为什么这是一个坏主意!!!

delete UserTable /*this is just here so you can run this code over and over*/

/*John Doe*/
declare @FirstName varchar(50) = 'John'
declare @LastName varchar(50) = 'Doe'
declare @newID varchar(50) = ''
while(@newID = '' or @newID in (select distinct ID from UserTable))
  begin
    select @newID = 'GM'+(select top 1 Possibility from PChars order by newid())+substring(@FirstName,1,1)+substring(@LastName,1,1)+(select top 1 Possibility from PChars order by newid())
  end
insert into UserTable select @newID,@FirstName,@LastName

/*Jane Doe*/
select @FirstName = 'Jane'
select @LastName = 'Doe'
select @newID = ''
while(@newID = '' or @newID in (select distinct ID from UserTable))
  begin
    select @newID = 'GM'+(select top 1 Possibility from PChars order by newid())+substring(@FirstName,1,1)+substring(@LastName,1,1)+(select top 1 Possibility from PChars order by newid())
  end
insert into UserTable select @newID,@FirstName,@LastName

select * from UserTable

以下是一些示例输出:

+--------+-----------+----------+
|   ID   | FirstName | LastName |
+--------+-----------+----------+
| GMOJDF | John      | Doe      |
| GM2JDD | Jane      | Doe      |
+--------+-----------+----------+

所以,我觉得我有点误解你的问题,但我认为这给你一个很好的启动点。