SQL Server:被GETDATE()所吸引

时间:2010-09-01 16:17:04

标签: sql-server sql-server-2005 tsql

我有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

http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/66507b8b-4a74-44c1-9637-3ab5f75db6a0

我发布的一个链接(标记答案)表明,在SQL 2005之前,GETDATE是确定性的 虽然SQL 2000 BOL声明GETDATE是不确定的

如果我使用数百万行进行更新

UPDATE tableName
SET dateColumn = GETDATE()

我知道你真的想做

DECLARE @DT datetime
SET @DT = GETDATE()
UPDATE table
SET datecol =@DT

我真的很困惑

预期的行为是什么?

  1. 如果我之前发布的选择声明
  2. 更新声明的行为
  3. 考虑到您正在更新包含1亿行的表上的日期字符串 datecolumn会有相同的日期和时间(以毫秒为单位)....

2 个答案:

答案 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())技巧逐行生成随机数......