似乎很明顯,如果您在 SQL Server 中呼叫 GETDATE() 的兩個執行批次在時間上有足夠的間隔,那么回傳值將是不同的。
另一方面,如果您快速連續呼叫GETDATE()兩次,您有可能從兩次呼叫中獲得相同的結果,因為結果的解析度是有限的。但這并不一定能保證,因為這兩次呼叫可能發生在結果解析度的倍數兩側的實時位置。
我的問題是:是否有任何范圍(在模糊的意義上)可以保證所有GETDATE()呼叫將回傳相同的值?如果你在同一個運算式中多次呼叫GETDATE()?對于一個DML陳述句中的單一行(但不同的運算式)?在單個陳述句的整個持續時間內?包括任何觸發器的執行?如果呼叫了一個用戶程序呢?
當做一個運算式來產生,例如,本月第一天的日期時,問題就出現了。
DATEADD(day, 1-DATEPART(day, GETDATE()), GETDATE())似乎是這樣做的方法,但是這只有在你100%確定兩個GETDATE呼叫回傳相同的值時才有效,即使你運行的代碼正好跨越一個月的最后一天和下個月的第一天之間的邊界。如果其中一個GETDATE呼叫可以回傳新的一個月的第一天的00:00:00.000時間,而另一個則回傳在此之前的一個單位的解析度,你將得到不想要的結果(剛剛結束的那個月的第二天,或者剛剛結束的那個月的最后一天,取決于哪個GETDATE呼叫回傳的結果更小。
你可以通過在執行DML陳述句之前將一個變數設定為GETDATE的結果,并參考該變數而不是在DML陳述句中呼叫GETDATE來在一定程度上回避這個問題;你呼叫的程式和觸發器仍然會得到它們自己的GETDATE值。
同樣的問題也適用于所有其他的日期獲取函式,如SYSDATETIME等,既包括對每個函式的多次呼叫,也包括對其中幾個函式的呼叫。
uj5u.com熱心網友回復:
幾乎所有內置的SQL Server函式都在每條陳述句中被評估一次,包括GETDATE()和RAND()。 NEWID()是一個明顯的例外,它在一個查詢中每行運行一次。
如圖所示
use tempdb
啟用
創建 或 修改 函式 fn_spin(@iters int)
returns int int
as
begin
declare @hash varbinary(2000) = 0x01
while @iters > 0
begin
set @hash = HASHBYTES('sha-512',@hash)
set @iters -= 1
end
return @iters;
end
去
select getdate()。
select top 10 dbo.fn_spin(1000000), getdate()
from sys.objects
unionall
select 1, getdate();
select getdate();
輸出
-----------------------。
2021-09-20 17:22:07.0401 row影響)
----------- -----------------------
0 20210920 17: 22: 07. 040: 22: 07.
0 20210920 17: 22: 07. 040: 22: 07.
0 20210920 17: 22: 07. 040: 22: 07.
0 20210920 17: 22: 07. 040: 22: 07.
0 20210920 17: 22: 07. 040: 22: 07.
0 20210920 17: 22: 07. 040: 22: 07.
0 20210920 17: 22: 07. 040: 22: 07.
0 20210920 17: 22: 07. 040: 22: 07.
0 20210920 17: 22: 07. 040: 22: 07.
0 20210920 17: 22: 07. 040: 22: 07.
1 20210920 17: 22: 07. 04011 rows影響)
-----------------------
2021-09-20 17:22:11.147
(1 row影響)
但是我認為這種行為在任何地方都沒有被記錄下來,所以雖然它不太可能改變,但你可能不應該依賴它,并為GETDATE()的回傳值分配一個變數,并在隨后的查詢中使用它。
uj5u.com熱心網友回復:
GETDATE()是一個 "運行時常量"。
- 如果你在同一個運算式中多次呼叫GETDATE()?可能是不同的。這不是一個無限回圈
WHILE DATEDIFF(MILLISECOND, GETDATE(), GETDATE()) = 0 回圈: - 對于一個DML陳述句中的單行(但不同的運算式)? 可以是不同的
- 對于一個單一陳述句的整個持續時間?是的,這是運行時的常態行為 。
- 包括任何執行的觸發器?不。如果觸發器呼叫
GETDATE(),這是一個不同的呼叫,所以可能是不同的 。
- 如果呼叫的是用戶程序呢?與觸發器相同
- 如果用戶程序被呼叫呢?
你有可能使用SESSION_CONTEXT來在父作用域中保存值,并使其在子作用域中可用(對觸發器最有用,因為你不能向其傳遞引數)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/323098.html
標籤:
上一篇:當npm審計修復/更新/收縮包裝手動更改不起作用時,如何更新node-sass的嵌套包ansi-regex?
下一篇:我如何在訂單中使用案例?
