一定期間スリープさせるだけのT-SQLコマンドを作成する方法はありますか?私は非同期でWebサービスを作成しており、非同期パターンが実際にそれをよりスケーラブルにするかどうかを確認するためにいくつかのテストを実行できるようにしたいと考えています。遅い外部サービスを「モック」するために、実行速度が遅いが実際には大量のものを処理していないスクリプトでSQLサーバーを呼び出すことができるようにしたいと思います。
一定期間スリープさせるだけのT-SQLコマンドを作成する方法はありますか?私は非同期でWebサービスを作成しており、非同期パターンが実際にそれをよりスケーラブルにするかどうかを確認するためにいくつかのテストを実行できるようにしたいと考えています。遅い外部サービスを「モック」するために、実行速度が遅いが実際には大量のものを処理していないスクリプトでSQLサーバーを呼び出すことができるようにしたいと思います。
回答:
WAITFORコマンドを見てください。
例えば
-- wait for 1 minute
WAITFOR DELAY '00:01'
-- wait for 1 second
WAITFOR DELAY '00:00:01'
このコマンドは高度な精度を可能にしますが、GetTickCountに依存しているため、通常のマシンでは10ms〜16ms 内でのみ正確です。したがって、たとえば、呼び出しWAITFOR DELAY '00:00:00:001'
はまったく待機しない可能性があります。
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
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
Only functions and some extended stored procedures can be executed from within a function.
MSドキュメントが好きではありません。ストアドプロシージャを使用した例を提供します
「時間」を「待機」することもできます。
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
PRINT
代わりに使用しないのはなぜRAISERROR
ですか?
以下は、CommandTimeoutをテストするための非常に単純なC#コードです。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();
}
}
}
}
}