我有SQL Server 2005 Standard Service Pack 2 9.00.4053.00(Intel X86)
表有近3000万行..
如果我这样做
SELECT GETDATE(), * FROM
<table>
返回相同的日期和时间值,包括毫秒部分 ..虽然查询花了3分多钟才完成...
我已经阅读了
http://sqlblog.com/blogs/andrew_kelly/archive/2008/02/27/when-getdate-is-not-a-constant.aspx
我发布的一个链接(标记答案)表明,在SQL 2005之前,GETDATE是确定性的 虽然SQL 2000 BOL声明GETDATE是不确定的
如果我使用数百万行进行更新
UPDATE tableName
SET dateColumn = GETDATE()
我知道你真的想做
DECLARE @DT datetime
SET @DT = GETDATE()
UPDATE table
SET datecol =@DT
我真的很困惑
预期的行为是什么?
考虑到您正在更新包含1亿行的表上的日期字符串 datecolumn会有相同的日期和时间(以毫秒为单位)....
答案 0 :(得分:10)
GetDate()
从未确定过。确定性意味着它在传递相同参数时将始终返回相同的结果。
与rand()
相同。每列评估一次,但一旦评估,对所有行保持相同。
使用rand()
比getdate()
select top 4 rand(), rand()
from sys.objects
退回
---------------------- ----------------------
0.0566172633850772 0.431111195699363
0.0566172633850772 0.431111195699363
0.0566172633850772 0.431111195699363
0.0566172633850772 0.431111195699363
如果您尝试以下
select top 10 getdate(), getdate()
from sys.objects
并查看实际执行计划中的ComputeScalar运算符属性,您将看到GetDate()
被评估两次。
注意:在SQL 2000(我不知道)之后,每列而不是每个查询的评估行为可能会发生变化,但这不是BOL定义为确定性的含义。
答案 1 :(得分:3)
根据马丁史密斯的回答,提到的决定论是udf行为的变化。在SQL Server 2000中,您无法在udf中使用GETDATE。您可以在SQL Server 2005中。See this link too
正如Martin Smith所说,每个查询对每列评估一些函数。不是每排。 GETDATE是一个,RAND是另一个。
如果确实需要逐行评估GETDATE,请将其包装在udf中。
编辑:
NEWID在统计上是独一无二的。必须逐行进行评估,这样您才能在另一行中显示相同的值。因此CHECKSUM(NEWID())
技巧逐行生成随机数......