Est-il possible d'écrire une commande T-SQL pour l'éteindre pendant un certain temps? J'écris un service Web de manière asynchrone et je veux être en mesure d'exécuter des tests pour voir si le modèle asynchrone va vraiment le rendre plus évolutif. Afin de "se moquer" d'un service externe qui est lent, je veux pouvoir appeler un serveur SQL avec un script qui tourne lentement, mais qui ne traite pas beaucoup de choses.Commande de veille dans T-SQL?
Répondre
regard sur 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 only accurate within 10ms - 16ms sur une machine typique car elle repose sur GetTickCount. Ainsi, par exemple, l'appel WAITFOR DELAY '00:00:00:001'
est susceptible d'entraîner aucune attente du tout.
Quelqu'un sait comment faire fonctionner une fonction? Je reçois (correctement probablement), mais pour des raisons de test, je voudrais remplacer) 'Utilisation invalide d'un opérateur d'effet secondaire' WAITFOR 'dans une fonction .... – monojohnny
@monojohnny pour obtenir un SVF à attendre, je' J'ai essayé la réponse de Josh ci-dessous mais ça n'a pas marché. Au lieu de cela, je crée simplement une boucle WHILE comme ceci: 'CREATE FUNCTION [dbo]. [ForcedTimeout] (@ secondes int) renvoie int comme BEGIN DECLARE @endTime datetime2 (0) = DATEADD (SECOND, @seconds, GETDATE()) ; PENDANT (GETDATE() <@endTime) BEGIN \t SET @endTime = @endTime; - Ne faites rien, mais SQL nécessite une déclaration. END' – GilesDMiddleton
Assurez-vous d'utiliser 3 chiffres pour les ms - '00: 00: 00: 01' n'est pas égal à '00: 00: 00: 010' utilisez le second. (testé sur MSSQL 2016) – Nick
Voici un morceau de code C# très simple pour tester le CommandTimeout avec. 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 à 0 ou quelque chose de plus élevé que 2 fonctionnera correctement. Par ailleurs, le CommandTimeout par défaut 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();
}
}
}
}
}
Si vous êtes en C#, vous devriez probablement utiliser Thread.currentThread.sleep (60000) ou Thread.sleep (60000) qui fait la même chose. De cette façon, votre délai est isolé pour votre application.Appelez ensuite votre logique de base de données ultérieure. –
@ActionDan Utilisation de Thread.Sleep ne va pas aider à exercer le CommandTimeout, n'est-ce pas. Comme un exemple artificiel, il fait ce qui est écrit sur la boîte. –
WAITFOR DELAY 'HH:MM:SS'
je crois que le temps maximum, cela peut attendre 23 heures, 59 minutes et 59 secondes.
Voici une fonction scalaire pour montrer son utilisation; la fonction ci-dessous prendra un paramètre entier de secondes, qu'elle traduit ensuite en HH: MM: SS et l'exécute en utilisant la commande EXEC sp_executesql @sqlcode
pour interroger. La fonction ci-dessous est à titre de démonstration seulement, je sais que ce n'est pas vraiment utile pour une fonction 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 retarder plus de 24 heures, je vous suggère d'utiliser un paramètre @Days aller pour un certain nombre de jours et 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
** SQL Azure ** n'aime pas ça 'Seules les fonctions et certaines procédures stockées étendues peuvent être exécutées à partir d'une fonction.' [MS Docs fournit un exemple en utilisant Sted Procs] (https://docs.microsoft.com/ en-us/sql/t-sql/langue-elements/waitfor-transact-sql # examples) - ressemble à cette approche invalide – SliverNinja
Vous pouvez également "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
Pourquoi ne pas utiliser 'PRINT' au lieu de' RAISERROR'? – slartidan
question juste! Je pourrais vouloir l'utiliser un jour. En aparté, c'est la première fois que j'entends parler de vouloir que la DB soit plus lente;) –
Je suis bogué en appelant un service asynchrone de T-SQL. – jmucchiello