在使用這個語句之前,我們先看看微軟官方給的幫助文檔里面對Waitfor的說明:
WAITFOR (Transact-SQL)
本文內容
適用於: SQL Server
Azure SQL 數據庫
Azure Synapse Analytics (SQL DW)
並行數據倉庫 APPLIES TO:
SQL Server
Azure SQL Database
Azure Synapse Analytics (SQL DW)
Parallel Data Warehouse
阻止執行批處理、存儲過程或事務,直到已過指定時間或時間間隔,或者指定語句發生修改或至少返回一行為止。Blocks the execution of a batch, stored procedure, or transaction until either a specified time or time interval elapses, or a specified statement modifies or returns at least one row.
Transact-SQL 語法約定
Transact-SQL Syntax Conventions
語法Syntax
WAITFOR { DELAY 'time_to_pass' | TIME 'time_to_execute' | [ ( receive_statement ) | ( get_conversation_group_statement ) ] [ , TIMEOUT timeout ] }
參數Arguments
DELAYDELAY
可以繼續執行批處理、存儲過程或事務之前必須經過的指定時段,最長可為 24 小時。Is the specified period of time that must pass, up to a maximum of 24 hours, before execution of a batch, stored procedure, or transaction proceeds.
'time_to_pass''time_to_pass'
等待的時段。Is the period of time to wait. time_to_pass 可以以“datetime”數據格式指定,也可以指定為局部變量 。time_to_pass can be specified either in a datetime data format, or as a local variable. 不能指定日期;因此,不允許指定“datetime”值的日期部分 。Dates can't be specified, so the date part of the datetime value isn't allowed. time_to_pass 將被格式化為 hh:mm[[:ss].mss] 。time_to_pass is formatted as hh:mm[[:ss].mss].
TIMETIME
指定的運行批處理、存儲過程或事務的時間。Is the specified time when the batch, stored procedure, or transaction runs.
'time_to_execute''time_to_execute'
WAITFOR 語句完成的時間。Is the time at which the WAITFOR statement finishes. 可以使用“datetime”數據格式指定 time_to_execute,也可以將其指定為局部變量 。time_to_execute can be specified in a datetime data format, or it can be specified as a local variable. 不能指定日期;因此,不允許指定“datetime”值的日期部分 。Dates can't be specified, so the date part of the datetime value isn't allowed. time_to_execute 將被格式化為 hh:mm[[:ss].mss],並且可以選擇包括 1900-01-01 的日期 。time_to_execute is formatted as hh:mm[[:ss].mss] and can optionally include the date of 1900-01-01.
receive_statementreceive_statement
有效的 RECEIVE 語句。Is a valid RECEIVE statement.
重要
包含 receive_statement 的 WAITFOR 僅適用於 消息Service BrokerService Broker。WAITFOR with a receive_statement is applicable only to Service BrokerService Broker messages. 有關詳細信息,請參閱 RECEIVE (Transact-SQL)。For more information, see RECEIVE (Transact-SQL).
get_conversation_group_statementget_conversation_group_statement
有效的 GET CONVERSATION GROUP 語句。Is a valid GET CONVERSATION GROUP statement.
重要
包含 get_conversation_group_statement 的 WAITFOR 僅適用於 消息Service BrokerService Broker。WAITFOR with a get_conversation_group_statement is applicable only to Service BrokerService Broker messages. 有關詳細信息,請參閱 GET CONVERSATION GROUP (Transact-SQL)。For more information, see GET CONVERSATION GROUP (Transact-SQL).
TIMEOUT timeout TIMEOUT timeout
指定消息到達隊列前等待的時間(以毫秒為單位)。Specifies the period of time, in milliseconds, to wait for a message to arrive on the queue.
重要
指定包含 TIMEOUT 的 WAITFOR 僅適用於 Service BrokerService Broker 消息。Specifying WAITFOR with TIMEOUT is applicable only to Service BrokerService Broker messages. 有關詳細信息,請參閱 RECEIVE (Transact-SQL) 和 GET CONVERSATION GROUP (Transact-SQL)。For more information, see RECEIVE (Transact-SQL) and GET CONVERSATION GROUP (Transact-SQL).
備注Remarks
執行 WAITFOR 語句時,事務正在運行,並且其他請求不能在同一事務下運行。While executing the WAITFOR statement, the transaction is running and no other requests can run under the same transaction.
實際的時間延遲可能與 time_to_pass、time_to_execute 或 timeout 中指定的時間不同,它依賴於服務器的活動級別 。The actual time delay may vary from the time specified in time_to_pass, time_to_execute, or timeout, and depends on the activity level of the server. 計划 WAITFOR 語句線程時,計時器開始計時。The time counter starts when the WAITFOR statement thread is scheduled. 如果服務器忙碌,則可能不會立即計划線程;因此,時間延遲可能比指定的時間要長。If the server is busy, the thread may not be immediately scheduled, so the time delay may be longer than the specified time.
WAITFOR 不更改查詢的語義。WAITFOR doesn't change the semantics of a query. 如果查詢不能返回任何行,WAITFOR 將一直等待,或等到滿足 TIMEOUT 條件(如果已指定)。If a query can't return any rows, WAITFOR will wait forever or until TIMEOUT is reached, if specified.
不能對 WAITFOR 語句打開游標。Cursors can't be opened on WAITFOR statements.
不能為 WAITFOR 語句定義視圖。Views can't be defined on WAITFOR statements.
如果查詢超出了 query wait 選項的值,則 WAITFOR 語句參數不運行即可完成。When the query exceeds the query wait option, the WAITFOR statement argument can complete without running. 有關詳細信息,請參閱配置 query wait 服務器配置選項。For more information about the configuration option, see Configure the query wait Server Configuration Option. 若要查看活動進程和正在等待的進程,請使用 sp_who。To see the active and waiting processes, use sp_who.
每個 WAITFOR 語句都有與其關聯的線程。Each WAITFOR statement has a thread associated with it. 如果對同一服務器指定了多個 WAITFOR 語句,可將等待這些語句運行的多個線程關聯起來。If many WAITFOR statements are specified on the same server, many threads can be tied up waiting for these statements to run. SQL ServerSQL Server 將監視 WAITFOR 語句線程數,並在服務器開始遇到線程資源不足的問題時,隨機選擇其中部分線程退出。monitors the number of WAITFOR statement threads, and randomly selects some of these threads to exit if the server starts to experience thread starvation.
如果某個事務鎖定了 WAITFOR 語句試圖訪問的行集以防止對行集進行更改,則可以在該事務中運行包含 WAITFOR 語句的查詢來創建死鎖。You can create a deadlock by running a query with WAITFOR within a transaction that also holds locks preventing changes to the rowset accessed by the WAITFOR statement. 如果存在上述死鎖,則 SQL ServerSQL Server 會標識這些情況並返回空結果集。SQL ServerSQL Server identifies these scenarios and returns an empty result set if the chance of such a deadlock exists.
注意
包含 WAITFOR 將減慢 SQL ServerSQL Server 過程的完成速度,並會導致應用程序中的超時消息。Including WAITFOR will slow the completion of the SQL ServerSQL Server process and can result in a timeout message in the application. 如有必要,請在應用程序級別調整連接的超時設置。If necessary, adjust the timeout setting for the connection at the application level.
示例Examples
A.A. 使用 WAITFOR TIMEUsing WAITFOR TIME
下面的示例在晚上 10:20 在 msdb 數據庫中執行 sp_update_job
存儲過程。The following example executes the stored procedure sp_update_job
in the msdb database at 10:20 P.M. (22:20
)。(22:20
).
EXECUTE sp_add_job @job_name = 'TestJob';
BEGIN
WAITFOR TIME '22:20';
EXECUTE sp_update_job @job_name = 'TestJob',
@new_name = 'UpdatedJob';
END;
GO
B.B. 使用 WAITFOR DELAYUsing WAITFOR DELAY
以下示例在兩小時的延遲后執行存儲過程。The following example executes the stored procedure after a two-hour delay.
BEGIN
WAITFOR DELAY '02:00';
EXECUTE sp_helpdb;
END;
GO
C.C. 在 WAITFOR DELAY 中使用局部變量Using WAITFOR DELAY with a local variable
以下示例顯示如何對 WAITFOR DELAY
選項使用局部變量。The following example shows how a local variable can be used with the WAITFOR DELAY
option. 該存儲過程將等待可變的時間段,然后將經過的小時、分鍾和秒數信息返回給用戶。This stored procedure waits for a variable period of time and then returns information to the user as the elapsed numbers of hours, minutes, and seconds.
IF OBJECT_ID('dbo.TimeDelay_hh_mm_ss','P') IS NOT NULL
DROP PROCEDURE dbo.TimeDelay_hh_mm_ss;
GO
CREATE PROCEDURE dbo.TimeDelay_hh_mm_ss
(
@DelayLength char(8)= '00:00:00'
)
AS
DECLARE @ReturnInfo varchar(255)
IF ISDATE('2000-01-01 ' + @DelayLength + '.000') = 0
BEGIN
SELECT @ReturnInfo = 'Invalid time ' + @DelayLength
+ ',hh:mm:ss, submitted.';
-- This PRINT statement is for testing, not use in production.
PRINT @ReturnInfo
RETURN(1)
END
BEGIN
WAITFOR DELAY @DelayLength
SELECT @ReturnInfo = 'A total time of ' + @DelayLength + ',
hh:mm:ss, has elapsed! Your time is up.'
-- This PRINT statement is for testing, not use in production.
PRINT @ReturnInfo;
END;
GO
/* This statement executes the dbo.TimeDelay_hh_mm_ss procedure. */
EXEC TimeDelay_hh_mm_ss '00:00:10';
GO
下面是結果集:Here is the result set.
A total time of 00:00:10, in hh:mm:ss, has elapsed. Your time is up.
另請參閱See Also
控制流語言 (Transact-SQL) Control-of-Flow Language (Transact-SQL)
datetime (Transact-SQL) datetime (Transact-SQL)
==============================================================================================
從上面的說明里,我們可以看到 TIMEOUT timeout 是可以精確到毫秒級的。
Datetime 格式的可以精確到毫秒,也就是10的負3次方秒,如對應獲取系統時間的方法:getdate()
Datetime2 格式的可以精確到微秒,也就是10的負6次方秒,如對應獲取系統時間的方法:sysdatetime()
正好,項目上有用到這塊的內容,就簡單的看看,研究下用法,我們先來測試看看。
延遲1毫秒
SELECT getdate()
WAITFOR DELAY '00:00:00.001'
SELECT getdate()
兩次的執行結果分別如下
2008-01-10 22:54:13.513
2008-01-10 22:54:13.513
兩次獲得的時間完全一樣。
延遲兩毫秒就能看返回的時間差別
SELECT getdate()
WAITFOR DELAY '00:00:00.002'
SELECT getdate()
延遲兩次的執行結果
2008-01-10 22:58:37.450
2008-01-10 22:58:37.467
由於我用的一個存儲過程中需要毫秒級的時間串產生序列號,因為沒有延遲,所以會出現序列號相同的問題,所以這個延遲函數就幫了大忙。
SELECT convert(varchar(8), getdate(),112) + replace(convert(varchar(12),getdate(),114),':','') as NewSerial
WAITFOR DELAY '00:00:00.002'
SELECT convert(varchar(8), getdate(),112) + replace(convert(varchar(12),getdate(),114),':','') as NewSerial
執行結果如下
20080110230256640
20080110230256653
出處:https://blog.csdn.net/jimlong/java/article/details/5862406