T-SQL 中的睡眠命令?

问题描述 投票:0回答:5

有没有办法编写一个T-SQL命令让它休眠一段时间?我正在异步编写一个 Web 服务,并且希望能够运行一些测试来查看异步模式是否真的会使其更具可扩展性。为了“模拟”缓慢的外部服务,我希望能够使用运行缓慢的脚本调用 SQL 服务器,但实际上并不处理大量内容。

sql-server t-sql asynchronous sleep
5个回答
732
投票

查看 WAITFOR 命令。

例如

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

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

此命令允许您实现高精度,但在典型机器上仅在 10ms - 16ms 内准确,因为它依赖于 GetTickCount。因此,例如,调用 WAITFOR DELAY '00:00:00:001'

 可能会导致根本不需要等待。 


14
投票
WAITFOR DELAY 'HH:MM:SS'

我相信最长可以等待的时间是23小时59分59秒。

这是一个标量值函数来展示它的用法;下面的函数将采用秒的整数参数,然后将其转换为 HH:MM:SS 并使用

EXEC sp_executesql @sqlcode

 命令进行查询来执行它。下面的函数仅用于演示,我知道它并不适合作为标量值函数! :-)

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

如果您希望延迟超过 24 小时,我建议您使用 @Days 参数来延迟几天并将函数可执行文件包装在循环中...例如..

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
投票
您还可以“等待”一段“时间”:

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
    

2
投票
这是一段非常简单的 C# 代码,用于测试 CommandTimeout。 它创建一个新命令,该命令将等待 2 秒。 将 CommandTimeout 设置为 1 秒,运行时您会看到异常。 将 CommandTimeout 设置为 0 或大于 2 的值即可正常运行。 顺便说一下,默认的 CommandTimeout 是 30 秒。

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
投票
这是一个很好的解决方案。

CREATE OR ALTER FUNCTION [dbo].[Sleep](@seconds INT) RETURNS INT AS BEGIN DECLARE @startTime DATETIME2(7) = SYSDATETIME(); DECLARE @endTime DATETIME2(7) = DATEADD(SECOND, @seconds, @startTime); WHILE (SYSDATETIME() < @endTime) SET @startTime = @startTime; RETURN @seconds; END GO CREATE OR ALTER VIEW dbo.SlowView AS SELECT [dbo].[Sleep](5) AS DELAY, NEWID() AS VALUE GO SELECT * FROM SlowView
    
© www.soinside.com 2019 - 2024. All rights reserved.