WAITFOR (Transact-SQL)

在达到指定时间或时间间隔之前,或者指定语句至少修改或返回一行之前,阻止执行批处理、存储过程或事务。

主题链接图标 Transact-SQL 语法约定

语法

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

参数

  • DELAY
    可以继续执行批处理、存储过程或事务之前必须经过的指定时段,最长可为 24 小时。

  • 'time_to_pass'
    等待的时段。 可以使用 datetime 数据可接受的格式之一指定 time_to_pass,也可以将其指定为局部变量。 不能指定日期;因此,不允许指定 datetime 值的日期部分。

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

  • 'time_to_execute'
    WAITFOR 语句完成的时间。 可以使用 datetime 数据可接受的格式之一指定 time_to_execute,也可以将其指定为局部变量。 不能指定日期;因此,不允许指定 datetime 值的日期部分。

  • receive_statement
    有效的 RECEIVE 语句。

    重要说明重要提示

    包含 receive_statement 的 WAITFOR 仅适用于 Service Broker 消息。 有关详细信息,请参阅 RECEIVE (Transact-SQL)

  • get_conversation_group_statement
    有效的 GET CONVERSATION GROUP 语句。

    重要说明重要提示

    包含 get_conversation_group_statement 的 WAITFOR 仅适用于 Service Broker 消息。 有关详细信息,请参阅 GET CONVERSATION GROUP (Transact-SQL)

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

    重要说明重要提示

    指定包含 TIMEOUT 的 WAITFOR 仅适用于 Service Broker 消息。 有关详细信息,请参阅 RECEIVE (Transact-SQL)GET CONVERSATION GROUP (Transact-SQL)

注释

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

实际的时间延迟可能与 time_to_pass、time_to_execute 或 timeout 中指定的时间不同,它依赖于服务器的活动级别。 时间计数器在计划完与 WAITFOR 语句关联的线程后启动。 如果服务器忙碌,则可能不会立即计划线程;因此,时间延迟可能比指定的时间要长。

WAITFOR 不更改查询的语义。 如果查询不能返回任何行,WAITFOR 将一直等待,或等到满足 TIMEOUT 条件(如果已指定)。

不能对 WAITFOR 语句打开游标。

不能为 WAITFOR 语句定义视图。

如果查询超过了 query wait 选项的值,则 WAITFOR 语句参数不运行即可完成。 有关该配置选项的详细信息,请参阅 配置查询等待值服务器配置选项。 若要查看活动进程和正在等待的进程,请使用 sp_who

每个 WAITFOR 语句都有与其关联的线程。 如果对同一服务器指定了多个 WAITFOR 语句,可将等待这些语句运行的多个线程关联起来。 SQL Server 将监视与 WAITFOR 语句关联的线程数,并在服务器开始遇到线程资源不足的问题时,随机选择其中部分线程退出。

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

注意事项注意

包含 WAITFOR 将减慢 SQL Server 过程的完成速度,并会导致应用程序中的超时消息。 如果需要,请在应用程序级别调整连接的超时设置。

示例

A.使用 WAITFOR TIME

以下示例在晚上 10:20 执行 sp_update_job 存储过程。 (22:20).

USE msdb;
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 选项使用局部变量。 将创建一个存储过程,该过程将等待可变的时间段,然后将经过的小时、分钟和秒数信息返回给用户。

USE AdventureWorks2012;
GO
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.

请参阅

参考

控制流语言 (Transact-SQL)

datetime (Transact-SQL)

sp_who (Transact-SQL)