Is there to way write a T-SQL command to just make it sleep for a period of time? I am writing a web service asynchronously and I want to be able to run some tests to see if the asynchronous pattern is really going to make it more scalable. In order to "mock" an external service that is slow, I want to be able to call a SQL server with a script that runs slowly, but isn't actually processing a ton of stuff.
-
23Fair question! I might want to use this sometime. As a complete aside, this is the first time I've ever heard of wanting the DB to be slower ;) – p.campbell Mar 20 '09 at 03:43
-
3I'm boggled by calling an asynchronous service from T-SQL. – jmucchiello Oct 07 '09 at 06:53
-
1Does this answer your question? [How to wait for 2 seconds?](https://stackoverflow.com/questions/7676164/how-to-wait-for-2-seconds) – Michael Freidgeim Jun 08 '22 at 23:54
4 Answers
Look at the WAITFOR command.
E.g.
-- wait for 1 minute
WAITFOR DELAY '00:01'
-- wait for 1 second
WAITFOR DELAY '00:00:01'
This command allows you a high degree of precision but is only accurate within 10ms - 16ms on a typical machine as it relies on GetTickCount. So, for example, the call WAITFOR DELAY '00:00:00:001'
is likely to result in no wait at all.

- 2,844
- 4
- 29
- 49

- 128,308
- 78
- 326
- 506
-
4Anybody know how to get this to work from a Function ? I get (correctly probably), but for the sake of testing I would like to override) 'Invalid use of a side-effecting operator 'WAITFOR' within a function.... – monojohnny Jun 07 '13 at 14:28
-
2@monojohnny to get a SVF to wait, I've tried Josh's answer below but it didn't work. Instead I just create a WHILE loop like this: `CREATE FUNCTION [dbo].[ForcedTimeout](@seconds int) returns int as BEGIN DECLARE @endTime datetime2(0) = DATEADD(SECOND, @seconds, GETDATE()); WHILE (GETDATE() < @endTime ) BEGIN SET @endTime = @endTime; -- do nothing, but SQL requires a statement. END` – GilesDMiddleton May 15 '17 at 08:57
-
4Make sure you use 3 digits for the ms - '00:00:00:01' is not equal to '00:00:00:010' use the second. (tested on MSSQL 2016) – Nick May 18 '17 at 20:36
-
1you can also try BEGIN TRANSACTION and END TRANSACTION if you need to block a table – Richárd Baldauf May 05 '20 at 19:25
-
Is `'00:00:00:001'` correct? The linked documentation states that the format is `hh:mm[[:ss].mss]` with a period while this answer uses a colon. – Trisped Feb 11 '21 at 17:25
WAITFOR DELAY 'HH:MM:SS'
I believe the maximum time this can wait for is 23 hours, 59 minutes and 59 seconds.
Here's a Scalar-valued function to show it's use; the below function will take an integer parameter of seconds, which it then translates into HH:MM:SS and executes it using the EXEC sp_executesql @sqlcode
command to query. Below function is for demonstration only, i know it's not fit for purpose really as a scalar-valued function! :-)
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
IF you wish to delay longer than 24 hours, I suggest you use a @Days parameter to go for a number of days and wrap the function executable inside a loop... e.g..
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

- 446
- 4
- 8
-
**SQL Azure** doesn't like this `Only functions and some extended stored procedures can be executed from within a function.` [MS Docs provide an example using Stored Procs](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/waitfor-transact-sql#examples) - looks like this approach is invalid – SliverNinja - MSFT Aug 10 '17 at 20:43
You can also "WAITFOR" a "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

- 342
- 3
- 5
-
2
-
8Because otherwise you would see nothing until after the entire wait finished. RAISERROR gives you the NOWAIT option, so it will show you print statements (essentially) in real time, as opposed to when the buffer is full or after the batch is completed. – Jeremy Giaco Jul 20 '18 at 02:00
Here is a very simple piece of C# code to test the CommandTimeout with. It creates a new command which will wait for 2 seconds. Set the CommandTimeout to 1 second and you will see an exception when running it. Setting the CommandTimeout to either 0 or something higher than 2 will run fine. By the way, the default CommandTimeout is 30 seconds.
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();
}
}
}
}
}

- 87
- 1
- 2
-
2If you are in c# you should probably use Thread.currentThread.sleep(60000) OR Thread.sleep(60000) which does the same thing. That way your delay is isolated to your application. Then call your subsequent database logic afterwards. – Action Dan Jul 06 '15 at 22:23
-
4@ActionDan Using Thread.Sleep is not going to help exercise the CommandTimeout though, is it. As a contrived example, it does what is written on the box. – Richard Hauer Jun 19 '16 at 11:40