Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

T-SQL: Use t-sql while routine return value in SELECT

I have a T-SQL routine that copies user information from one table 'Radius' to another 'Tags'. However, as the rows are transfered, I would also like to include a unique randomly generated code in the INSERT (3 chars long). The code is generated by the WHILE loop below. Any way to do this?

INSERT Tags (UserID, JobID, Code) 
SELECT UserID, @JobID,  ?????
FROM Radius

Unique random code generator:

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

CLARIFICATION: The reason for doing this is that I want to keep the random code generation logic at the level of the SQL stack. Implementing this in the app code would require me to check the db everytime a potential random code is generated to see if it is unique. As the number of code records increases so will the number of calls to the db as probability increases that there will be more duplicate codes generated before a unique one is generated.

like image 228
Jason Avatar asked May 22 '26 14:05

Jason


1 Answers

Part One, Generate a table with all possible values

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

This is a one off operation and takes around 1 second to run on SQL Azure. Now that you have all possible values in a table any future inserts become, something along the lines of

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

Before going with any of these schemes you had better be certain that you are not going to have more than 46656 rows in your table otherwise you will run out of unique ID Values.

like image 80
David Steele Avatar answered May 25 '26 02:05

David Steele



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!