web-dev-qa-db-fra.com

Commande de veille dans T-SQL?

Y a-t-il moyen d'écrire une commande T-SQL juste pour la mettre en veille pendant un certain temps? J'écris un service Web de manière asynchrone et je veux pouvoir exécuter des tests pour voir si le modèle asynchrone va réellement le rendre plus évolutif. Afin de "simuler" un service externe lent, je souhaite pouvoir appeler un serveur SQL avec un script qui s'exécute lentement, mais ne traite pas réellement une tonne de choses.

350
skb

regardez la commande WAITFOR

Par exemple.

-- wait for 1 minute
WAITFOR DELAY '00:01'

-- wait for 1 second
WAITFOR DELAY '00:00:01'

Cette commande vous permet un haut degré de précision mais est précise seulement entre 10ms et 16ms sur une machine typique car elle repose sur GetTickCount . Ainsi, par exemple, l'appel WAITFOR DELAY '00:00:00:001' risque de ne pas attendre du tout.

581
Sam Saffron
WAITFOR DELAY 'HH:MM:SS'

Je crois que le temps maximum que cela peut attendre est de 23 heures, 59 minutes et 59 secondes.

Voici une fonction à valeur scalaire pour montrer son utilisation; la fonction ci-dessous prendra un paramètre entier de secondes qu'il traduira ensuite en HH: MM: SS et l'exécutera à l'aide de la commande EXEC sp_executesql @sqlcode à interroger. La fonction ci-dessous est uniquement destinée à la démonstration, je sais que ce n'est pas vraiment adapté à une fonction réellement scalaire! :-)

    CREATE FUNCTION [dbo].[ufn_DelayFor_MaxTimeIs24Hours]
    (
    @sec int
    )
    RETURNS
    nvarchar(4)
    AS
    BEGIN


    declare @hours int = @sec / 60 / 60
    declare @mins int = (@sec / 60) - (@hours * 60)
    declare @secs int = (@sec - ((@hours * 60) * 60)) - (@mins * 60)


    IF @hours > 23 
    BEGIN
    select @hours = 23
    select @mins = 59
    select @secs = 59
    -- 'maximum wait time is 23 hours, 59 minutes and 59 seconds.'
    END


    declare @sql nvarchar(24) = 'WAITFOR DELAY '+char(39)+cast(@hours as nvarchar(2))+':'+CAST(@mins as nvarchar(2))+':'+CAST(@secs as nvarchar(2))+char(39)


    exec sp_executesql @sql

    return ''
    END

Si vous souhaitez différer plus de 24 heures, je vous suggère d’utiliser un paramètre @Days pendant un certain nombre de jours et d’envelopper la fonction exécutable dans une boucle ... par exemple.

    Declare @Days int = 5
    Declare @CurrentDay int = 1

    WHILE @CurrentDay <= @Days
    BEGIN

    --24 hours, function will run for 23 hours, 59 minutes, 59 seconds per run.
    [ufn_DelayFor_MaxTimeIs24Hours] 86400

    SELECT @CurrentDay = @CurrentDay + 1
    END
8
Josh Harris

Vous pouvez aussi "WAITFOR" un "TIME":

    RAISERROR('Im about to wait for a certain time...', 0, 1) WITH NOWAIT
    WAITFOR TIME '16:43:30.000'
    RAISERROR('I waited!', 0, 1) WITH NOWAIT
4
Jeremy Giaco

Voici un morceau de code C # très simple pour tester le CommandTimeout. Il crée une nouvelle commande qui attendra 2 secondes. Définissez CommandTimeout sur 1 seconde et vous verrez une exception lors de son exécution. Définir le CommandTimeout sur 0 ou quelque chose de supérieur à 2 fonctionnera correctement. Au fait, le temps par défaut de CommandTimeout est de 30 secondes.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Data.SqlClient;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      var builder = new SqlConnectionStringBuilder();
      builder.DataSource = "localhost";
      builder.IntegratedSecurity = true;
      builder.InitialCatalog = "master";

      var connectionString = builder.ConnectionString;

      using (var connection = new SqlConnection(connectionString))
      {
        connection.Open();

        using (var command = connection.CreateCommand())
        {
          command.CommandText = "WAITFOR DELAY '00:00:02'";
          command.CommandTimeout = 1;

          command.ExecuteNonQuery();
        }
      }
    }
  }
}
0
user2192239