ren*_*ren 6 sql-server concurrency getdate
假设
isnull(some_column, getdate()) >= getdate()
Run Code Online (Sandbox Code Playgroud)
其中逻辑是,如果some_column为null,则此表达式应始终为true.然而,这总是如此(因为在两次getdate()评估之间已经过了一段时间并且它们不会相等)?
不,不安全.您正面临所谓的运行时常量表达式,其中的GETDATE()是书架示例,它在查询启动时计算一次,然后使用缓存的计算值.但是,每次出现都要单独评估一次,并且两次评估可以落在日期时间精度边界的不同侧,从而产生两个不同的值.
一个简单的测试揭示了这种情况:
declare @cnt int = 0, @i int = 0
while @cnt = 0
begin
select @cnt = count(*)
from master..spt_values
where getdate() != getdate();
set @i += 1;
if @cnt != 0
raiserror(N'@cnt = %d this shoudl not happen but it dit after @i = %d', 16, 1, @cnt, @i);
end
Run Code Online (Sandbox Code Playgroud)
在我的情况下,这是立即被击中:
Msg 50000, Level 16, State 1, Line 9
@cnt = 2515 this shoudl not happen but it dit after @i = 694
Run Code Online (Sandbox Code Playgroud)
我没有解决如何更好地做到这一点的问题(你已经有了很多建议),但是关于运行时执行的假设是否正确(不是)的基本问题:
GETDATE() 两次声明将被评估两次
| 归档时间: |
|
| 查看次数: |
720 次 |
| 最近记录: |