The CRYPT_GEN_RANDOM function in Elias's answer made me work on a better solution:
CREATE FUNCTION dbo.MyRAND(@Seed as bigint) RETURNS float(53) AS BEGIN --Sample: SELECT dbo.MyRAND(DEFAULT), dbo.MyRAND(DEFAULT), dbo.MyRAND(12345) FROM ( SELECT 1 AS ID UNION SELECT 2 UNION SELECT 3 ) as ThreeRows DECLARE @Return as float(53) IF @Seed = 0 SET @Return = (Cast(CRYPT_GEN_RANDOM(8) as bigint) + POWER(Cast(2 as float(53)), 63)) / POWER(2.0, 64) ELSE SET @Return = (Cast(CRYPT_GEN_RANDOM(8, CAST(@Seed AS varbinary(8))) as bigint) + POWER(Cast(2 as float(53)), 63)) / POWER(2.0, 64) RETURN @Return END
This creates the same float between 0 and 1 as RAND (), so it can fall where the seed is not used. It will also be called based on each row, as shown by the pattern. However, unlike RAND using the same seed, it does not produce the same result.
Note
This doesn't work anymore:
Select @@Version Microsoft SQL Server 2014 - 12.0.4100.1 (Intel X86) Apr 20 2015 17:34:37 Copyright (c) Microsoft Corporation Developer Edition on Windows NT 6.1 <X64> (Build 7601: ) (WOW64)
but
Msg 443, Level 16, State 1, Procedure MyRAND, Line 10 Invalid use of a side-effecting operator 'Crypt_Gen_Random' within a function.
Stephen turner
source share