• SQL Server 中 WaitFor 延时执行的用法


    在使用这个语句之前,我们先看看微软官方给的帮助文档里面对Waitfor的说明:


    WAITFOR (Transact-SQL)

    本文内容

    1. 语法
    2. 参数
    3. 备注
    4. 示例
    5. 另请参阅

    适用于: 是SQL Server 是Azure SQL 数据库 否Azure Synapse Analytics (SQL DW) 否并行数据仓库 APPLIES TO: YesSQL Server YesAzure SQL Database NoAzure Synapse Analytics (SQL DW) NoParallel 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 语法约定Topic link icon Transact-SQL Syntax Conventions

    语法Syntax

    syntaxsql
      
    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 BrokerWAITFOR 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 BrokerWAITFOR 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_whoTo 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) 

    出处:https://docs.microsoft.com/zh-cn/sql/t-sql/language-elements/waitfor-transact-sql?view=sql-server-ver15

    ==============================================================================================

    从上面的说明里,我们可以看到  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

  • 相关阅读:
    Ubuntu 14.04 LTS Server 无法挂载光盘 启动initramfs等问题
    Linux的交叉编译 及configure配置
    大话设计模式读书笔记(五) 代理模式
    大话设计模式读书笔记(三) 单一职责原则和开放-封闭原则和依赖倒转原则
    大话设计模式读书笔记(二) 策略模式
    Java NIO(一) 初步理解NIO
    大话设计模式读书笔记(一) 简单工厂模式
    多线程设计模式(一) Single Threaded Execution
    多线程详细解析(二) 线程的共享互斥与线程的协调
    多线程详细解析(一) 创建线程
  • 原文地址:https://www.cnblogs.com/mq0036/p/12857143.html
Copyright © 2020-2023  润新知