我想在sql server中创建一个表并用数据填充(人们的信息)。目标是让每个人在第一行中获得一个唯一ID,该ID必须以固定字母GM
开头,后跟A-Z
或2-9
数字,名字的首字母,姓氏的首字母和A-Z
或2-9
。
答案 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)]
这种设置会给你带来很多麻烦,但它确实可行。请注意,据我了解你的要求,在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 | +--------+-----------+----------+
所以,我觉得我有点误解你的问题,但我认为这给你一个很好的启动点。