我正在回答问题hereabouts并在发布之前启动了我的SSMS测试一个小查询,但得到了一些奇怪的结果。这是查询:
UPDATE Person
SET Pos_X = Rand()
, Pos_Y = Rand(id)
SELECT ID, Surname, Forename, Pos_X, Pos_Y FROM Person
以下是结果集:
1 Bloggs Fred 0.332720913214171 0.713591993212924
2 Doe Jane 0.332720913214171 0.713610626184182
3 Smith Mary 0.332720913214171 0.71362925915544
4 Jones Martha 0.332720913214171 0.713647892126698
5 Jones Martha 0.332720913214171 0.713666525097956
6 Jones Martha 0.332720913214171 0.713685158069215
7 Jones Martha 0.332720913214171 0.713703791040473
8 Jones Martha 0.332720913214171 0.713722424011731
9 Jones Martha 0.332720913214171 0.713741056982989
正如我所预料的那样没有种子的兰德在每一行都会得到相同的结果,但是我希望带有种子的兰特(只有1到9号的数据)会比在0.0002之内的有序列表好一点!
你得到的相同吗?这听起来好像可以让人不知所措。
我确信这是相关的:
@@Version = 'Microsoft SQL Server 2005 - 9.00.5000.00 (Intel X86) Dec 10 2010 10:56:29 Copyright (c) 1988-2005 Microsoft Corporation Express Edition on Windows NT 6.1 (Build 7601: Service Pack 1) '
答案 0 :(得分:15)
答案 1 :(得分:4)
请尝试使用以下查询,该查询始终提供所需的随机数。
SELECT RAND(CAST(RIGHT(CAST(CAST(CRYPT_GEN_RANDOM(4)
AS INT) AS VARCHAR(100)), 1) AS INT))
更新:根据对话,我改变了我的答案如下:
SELECT CAST(CRYPT_GEN_RANDOM(4) AS INT)
答案 2 :(得分:3)
Elias的答案中的CRYPT_GEN_RANDOM功能让我开始研究更好的解决方案:
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
这产生了与RAND()应该在0和1之间相同的浮点数,因此可能会在没有使用种子的地方掉落。如样本所示,它也将按行进行调用。然而,与使用相同种子的RAND不同,不会产生相同的结果。
请注意
这不再适用于:
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)
作为
Msg 443, Level 16, State 1, Procedure MyRAND, Line 10
Invalid use of a side-effecting operator 'Crypt_Gen_Random' within a function.
答案 3 :(得分:1)
确保每行单独调用rand(),执行以下操作:
create view wrapped_rand_view
as
select rand( ) as random_value
go
create function wrapped_rand()
returns float as
begin
declare @f float
set @f = (select random_value from wrapped_rand_view)
return @f
end
select
ThreeRows.ID, dbo.wrapped_rand() wrapped_rand
from
( SELECT 1 AS ID UNION SELECT 2 UNION SELECT 3 ) as ThreeRows