我有一个T-SQL例程,可以将用户信息从一个表'Radius'复制到另一个'Radius'。但是,当行被传输时,我还想在INSERT中包含一个独特的随机生成的代码(3个字符长)。代码由下面的WHILE循环生成。有什么办法吗?
INSERT Tags (UserID, JobID, Code)
SELECT UserID, @JobID, ?????
FROM Radius
独特的随机代码生成器:
WHILE EXISTS (SELECT * FROM Tags WHERE Code = @code)
BEGIN
select @code=@code+char(n) from
(
select top 3 number as n from master..spt_values
where type='p' and number between 48 and 57 or number between 65 and 90
order by newid()
)
END
澄清:这样做的原因是我希望将随机代码生成逻辑保持在SQL堆栈的级别。在应用程序代码中实现这一点需要我每次生成潜在的随机代码时检查数据库,看它是否是唯一的。随着代码记录数量的增加,对db的调用次数随着概率的增加而增加,在生成唯一代码之前会生成更多的重复代码。
答案 0 :(得分:5)
第一部分,生成一个包含所有可能值的表
DECLARE @i int
CREATE TABLE #AllChars(value CHAR(1))
SET @i=48
WHILE @i<=57
BEGIN
INSERT INTO #Allchars(value) VALUES(CHAR(@i))
SET @i=@i+1
END
SET @i=65
WHILE @i<=90
BEGIN
INSERT INTO #Allchars(value) VALUES(CHAR(@i))
SET @i=@i+1
END
CREATE TABLE AllCodes(value CHAR(3),
CONSTRAINT PK_AllChars PRIMARY KEY CLUSTERED(value))
INSERT INTO AllCodes(value)
SELECT AllChars1.Value+AllChars2.Value+AllChars3.Value
FROM #AllChars AS AllChars1,#AllChars AS AllChars2,#AllChars AS AllChars3
这是一次性操作,在SQL Azure上运行大约需要1秒。既然你在表格中拥有了所有可能的值,那么未来的插入就会变成
SELECT
RadiusTable.UserID,
RadiusTable.JobID,
IDTable.Value
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY UserID,JobID) As RadiusRow,
UserID,JobID
FROM Radius
) AS RadiusTable INNER JOIN
(
SELECT ROW_NUMBER() OVER (ORDER BY newID()) As IDRow,
Value
FROM AllCodes
) AS IDTable ON RadiusTable.RadiusRow = IDTable.IDRow
在使用任何这些方案之前,最好确定您的表中不会有超过46656行,否则您将用尽唯一的ID值。
答案 1 :(得分:4)
我不知道这是否可能适合你的情况,但对我而言,标量值函数似乎是一个解决方案。
答案 2 :(得分:1)
好吧,让我重新开始吧。
这看起来很丑陋,但可能有用:newid() inside sql server function
接受的答案是。
啊,那也是那样做的。这个问题是我使用的是Asp.net调用的T-SQL存储过程我在哪里放置CREATE VIEW语句?我无法将其添加到函数文件中。