WAITFOR (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Microsoft Fabric 预览版中的 SQL 数据库

阻止执行批处理、存储过程或事务,直到已过指定时间或时间间隔,或者指定语句发生修改或至少返回一行为止。

Transact-SQL 语法约定

Syntax

WAITFOR
{
    DELAY 'time_to_pass'
  | TIME 'time_to_execute'
  | [ ( receive_statement ) | ( get_conversation_group_statement ) ]
    [ , TIMEOUT timeout ]
}

Arguments

DELAY

在批处理、存储过程或事务执行之前,必须经过的指定时间段(最长为 24 小时)。

'time_to_pass'

等待的时间段。 time_to_pass可以 采用 日期/时间 数据格式指定,也可以指定为局部变量。 无法指定日期,因此不允许 日期时间值的日期 部分。 time_to_pass 的格式设置为 hh:mm[[:ss].fff].

TIME

批处理、存储过程或事务运行时的指定时间。

'time_to_execute'

WAITFOR 语句完成的时间。 time_to_execute 可以 采用日期/时间 数据格式指定,也可以将其指定为局部变量。 无法指定日期,因此不允许 日期时间值的日期 部分。 time_to_execute 的格式设置为 hh:mm[[:ss].fff] ,可以选择包含日期 1900-01-01

receive_statement

仅适用于:Service Broker 消息。 有关详细信息,请参阅 RECEIVE

有效 RECEIVE 语句。

get_conversation_group_statement

仅适用于:Service Broker 消息。 有关详细信息,请参阅 GET CONVERSATION GROUP

有效 GET CONVERSATION GROUP 语句。

TIMEOUT timeout

仅适用于:Service Broker 消息。 有关详细信息,请参阅 RECEIVEGET CONVERSATION GROUP

指定消息到达队列前等待的时间(以毫秒为单位)。

Remarks

WAITFOR执行语句时,事务正在运行,其他任何请求都不能在同一事务下运行。

实际时间延迟可能与 time_to_passtime_to_execute超时中指定的时间不同,具体取决于服务器的活动级别。 计划语句线程时 WAITFOR ,时间计数器将启动。 如果服务器繁忙,则线程可能不会立即计划,因此时间延迟时间可能比指定的时间长。

WAITFOR 不会更改查询的语义。 如果查询无法返回任何行, WAITFOR 则等待永久或直到 TIMEOUT 达到,如果指定。

不能对 WAITFOR 语句打开游标。

不能对 WAITFOR 语句定义视图。

当查询超过查询等待选项时, WAITFOR 语句参数可以在不运行的情况下完成。 有关配置选项的详细信息,请参阅 服务器配置:查询等待。 若要查看活动进程和等待进程,请使用 sp_who

每个 WAITFOR 语句都有一个与之关联的线程。 如果在同一服务器上指定了多个 WAITFOR 语句,则可以绑定多个线程,等待这些语句运行。 SQL Server 监视语句线程数 WAITFOR ,并在服务器开始遇到线程不足时随机选择其中一些线程退出。

可以通过在事务中运行包含 WAITFOR 锁的查询来创建死锁,从而防止对语句访问 WAITFOR 的行集进行更改。 如果存在上述死锁,则 SQL Server 会标识这些情况并返回空结果集。

Caution

包括 WAITFOR 减慢 SQL Server 进程的完成速度,并可能导致应用程序中出现超时消息。 如有必要,请在应用程序级别调整连接的超时设置。

Examples

A. 使用 WAITFOR TIME

以下示例在sp_update_job下午 10:20(msdb) 处执行数据库中的存储过程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. 使用 WAITFOR DELAY

以下示例在两小时的延迟后执行存储过程。

BEGIN
    WAITFOR DELAY '02:00';
    EXECUTE sp_helpdb;
END;
GO

C. 将 WAITFOR DELAY 与局部变量配合使用

以下示例显示如何对 WAITFOR DELAY 选项使用局部变量。 该存储过程将等待可变的时间段,然后将经过的小时、分钟和秒数信息返回给用户。

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

结果集如下。

A total time of 00:00:10, in hh:mm:ss, has elapsed. Your time is up.