The following function function will return you a random string of the specified characters, for a length of between @StrLenLo and @StrLenHi. The only ‘Oddity’ with using this function is that if the parameters are not dependant upon data within a table SQLServer will create a hash join which will cause the same value to be returned. This is the reason for the bizzare looking ‘case when Num>=0 then 8 else 8 end’
First off generate a ‘numbers’ table
CREATE TABLE dbo.Numbers (Num INT NOT NULL PRIMARY KEY CLUSTERED);
GO
DECLARE @i INT;
SELECT @i = 1;
WHILE @i <= 1000
BEGIN
INSERT INTO dbo.Numbers(Num) VALUES (@i);
SELECT @i = @i + 1;
END;
go
update statistics Numbers with fullscan
go
Then , as SqlServer does not allow the use of newid() within functions create a small view that will return a random integer.
drop View VwNewCheck
go
Create View VwNewCheck
with schemabinding
as
Select abs(checksum(NewId())) as New_Id
go
Next up the actual function
Drop Function GetVariableLengthRandomCode
go
Create Function GetVariableLengthRandomCode(@StrLenLo integer,@StrLenHi integer,@CharsNeeded char(62))
returns table
with schemabinding
as
return
(
with cteRandomLength(StrLen)
as
(
Select @StrLenLo + VwNewCheck.new_id%((@StrLenHi+1)-@StrLenLo)
from dbo.VwNewCheck
),
cteRandomChars(num,c)
as
(
Select Num,substring(@CharsNeeded,(Select VwNewCheck.new_id%(len(@CharsNeeded)-1)+1 from dbo.VwNewCheck where num = num ),1)
from dbo.numbers
where Num <= (Select StrLen from cteRandomLength)
)
select (
select c as [text()]
from cteRandomChars
for xml path('')) as random
)
go
And you are good to go.
select * from GetVariableLengthRandomCode(8,16,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')
As mentioned above if you execute
select Random from numbers cross apply GetVariableLengthRandomCode(8,16,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')
Then the same value will be returned a thousand times, so fool the optimizer by
select Random
from numbers
cross apply GetVariableLengthRandomCode(case when Num>=0 then 8 else 8 end,16,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')
and you will get a thousand random strings between 8 and 16 characters long.