WAITFOR (Transact-SQL)

Bloquea la ejecución de un lote, un procedimiento almacenado o una transacción hasta alcanzar la hora o el intervalo de tiempo especificado, o hasta que una instrucción especificada modifique o devuelva al menos una fila.

Icono de vínculo a temasConvenciones de sintaxis de Transact-SQL

Sintaxis

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

Argumentos

  • DELAY
    Es el período de tiempo especificado (hasta un máximo de 24 horas) que debe transcurrir antes de la ejecución de un lote, un procedimiento almacenado o una transacción.

  • 'time_to_pass'
    Es el período de tiempo que hay que esperar. time_to_pass se puede especificar en uno de los formatos aceptados para el tipo de datos datetime o como una variable local. No se pueden especificar fechas; por lo tanto, no se permite la parte de fecha del valor datetime.

  • TIME
    Es la hora especificada a la que se ejecuta el lote, el procedimiento almacenado o la transacción.

  • 'time_to_execute'
    Es la hora a la que termina la instrucción WAITFOR. time_to_execute se puede especificar en uno de los formatos aceptados para el tipo de datos datetime o como una variable local. No se pueden especificar fechas; por lo tanto, no se permite la parte de fecha del valor datetime.

  • receive_statement
    Es una instrucción RECEIVE válida.

    Nota importanteImportante

    WAITFOR con receive_statement sólo es aplicable a los mensajes de Service Broker. Para obtener más información, vea RECEIVE (Transact-SQL).

  • get_conversation_group_statement
    Es una instrucción GET CONVERSATION GROUP válida.

    Nota importanteImportante

    WAITFOR con get_conversation_group_statement sólo es aplicable a los mensajes de Service Broker. Para obtener más información, vea GET CONVERSATION GROUP (Transact-SQL).

  • TIMEOUT timeout
    Especifica el período de tiempo, en milisegundos, que se espera a que llegue un mensaje en la cola.

    Nota importanteImportante

    Sólo se puede especificar WAITFOR con TIMEOUT en mensajes de Service Broker. Para obtener más información, vea RECEIVE (Transact-SQL) y GET CONVERSATION GROUP (Transact-SQL).

Notas

La transacción se está ejecutando mientras se ejecuta la instrucción WAITFOR y no se puede ejecutar ninguna otra solicitud para la misma transacción.

El retardo de tiempo real puede variar del tiempo especificado en time_to_pass, time_to_execute o timeout, y depende del nivel de actividad del servidor. El contador de tiempo se inicia cuando se programa el subproceso asociado a la instrucción WAITFOR. Si el servidor está ocupado, es posible que no se programe el subproceso inmediatamente; por tanto, el retardo de tiempo puede ser mayor que el tiempo especificado.

WAITFOR no cambia la semántica de una consulta. Si una consulta no devuelve ninguna fila, WAITFOR esperará indefinidamente o hasta que se alcance el valor de TIMEOUT, si está especificado.

No se pueden abrir cursores en las instrucciones WAITFOR.

No se pueden definir vistas en las instrucciones WAITFOR.

Cuando una consulta supera la opción querywait, se puede completar el argumento de la instrucción WAITFOR sin ejecutarse. Para obtener más información sobre esta opción de configuración, vea query wait (opción). Para ver los procesos activos y en espera, utilice sp_who.

Cada instrucción WAITFOR tiene un subproceso asociado. Si se especifica un gran número de instrucciones WAITFOR en el mismo servidor, se pueden acumular muchos subprocesos a la espera de que se ejecuten estas instrucciones. SQL Server supervisa el número de subprocesos asociados con las instrucciones WAITFOR y selecciona aleatoriamente algunos de estos subprocesos para salir si el servidor empieza a experimentar la falta de subprocesos.

Puede crear un interbloqueo ejecutando una consulta con WAITFOR en una transacción que también tenga bloqueos que impidan realizar cambios en el conjunto de filas al que intenta tener acceso la instrucción WAITFOR. SQL Server identifica estos escenarios y devuelve un conjunto de resultados vacío si existe la posibilidad de un interbloqueo de este tipo.

Ejemplos

A. Utilizar WAITFOR TIME

Este ejemplo ejecuta el procedimiento almacenado sp_update_job a las 10:20 p. m. (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. Utilizar WAITFOR DELAY

En el ejemplo siguiente se ejecuta el procedimiento almacenado después de un retardo de dos horas.

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

C. Usar WAITFOR DELAY con una variable local

En el ejemplo siguiente se muestra cómo se puede utilizar una variable local con la opción WAITFOR DELAY. Se crea un procedimiento almacenado que espere un período de tiempo variable y, a continuación, devuelva información al usuario acerca del número de horas, minutos y segundos que han transcurrido.

USE AdventureWorks;
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

Éste es el conjunto de resultados.

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