T- एसक्यूएल में स्लीप कमांड?


364

क्या टी-एसक्यूएल कमांड लिखने का तरीका सिर्फ समय की नींद के लिए है? मैं एसिंक्रोनस रूप से एक वेब सेवा लिख ​​रहा हूं और मैं यह देखने के लिए कुछ परीक्षण चलाने में सक्षम होना चाहता हूं कि क्या अतुल्यकालिक पैटर्न वास्तव में इसे और अधिक स्केलेबल बनाने जा रहा है। एक बाहरी सेवा को धीमा करने के लिए "मॉक" करने के लिए, मैं एक स्क्रिप्ट के साथ SQL सर्वर को कॉल करने में सक्षम होना चाहता हूं जो धीरे-धीरे चलता है, लेकिन वास्तव में एक टन सामान को संसाधित नहीं कर रहा है।


19
निष्पक्ष प्रश्न! मैं कुछ समय के लिए इस का उपयोग करना चाहते हो सकता है। पूरी तरह से एक तरफ, यह पहली बार है जब मैंने DB को धीमा होने के बारे में कभी सुना है;)
p.campbell

2
मैं टी-एसक्यूएल से एक अतुल्यकालिक सेवा कॉल करके चकित हूँ।
jmucchiello

जवाबों:


616

को देखो WAITFOR आदेश।

उदाहरण के लिए

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

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

यह कमांड आपको उच्च स्तर की सटीकता की अनुमति देता है, लेकिन केवल एक विशिष्ट मशीन पर 10ms - 16ms के भीतर ही सटीक होता है क्योंकि यह गेटटीकाउंट पर निर्भर करता है । इसलिए, उदाहरण के लिए, इस कॉल के WAITFOR DELAY '00:00:00:001'परिणामस्वरूप कोई प्रतीक्षा नहीं की जा सकती है।


4
किसी को पता है कि यह कैसे एक समारोह से काम करने के लिए? मुझे मिलता है (शायद सही तरीके से), लेकिन परीक्षण के लिए मैं ओवरराइड करना चाहूंगा) 'एक समारोह के भीतर एक साइड-
इफ़ेक्टिंग

2
@monojohnny को एसवीएफ पाने के लिए प्रतीक्षा करने के लिए, मैंने जोश के जवाब की कोशिश की है, लेकिन यह काम नहीं किया। इसके बजाय मैं सिर्फ इस तरह एक WHILE लूप 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
बनाता हूं

3
सुनिश्चित करें कि आप ms के लिए 3 अंकों का उपयोग करते हैं - '00: 00: 00: 01 'के बराबर नहीं है '00: 00: 00: 010' दूसरे का उपयोग करें। (MSSQL 2016 पर परीक्षण किया गया)
निक

यदि आप एक तालिका को ब्लॉक करने की आवश्यकता है, तो आप BEGIN परिवहन और END परिवहन की कोशिश कर सकते हैं
रिचड बलडौफ

9
WAITFOR DELAY 'HH:MM:SS'

मेरा मानना ​​है कि यह अधिकतम समय 23 घंटे, 59 मिनट और 59 सेकंड है।

यह दिखाने के लिए यहां एक स्केलर-मूल्यवान फ़ंक्शन है; नीचे फ़ंक्शन सेकंड का पूर्णांक पैरामीटर लेगा, जो तब एचएच: एमएम: एसएस में अनुवाद करता है और 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

SQL Azure को यह पसंद नहीं है कि Only functions and some extended stored procedures can be executed from within a function. MS डॉक्स Stored Procs का उपयोग करके एक उदाहरण प्रदान करते हैं - ऐसा लगता है कि यह दृष्टिकोण अमान्य है
SliverNinja - MSFT

5

आप "WAITFOR" को "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

2
के PRINTबजाय का उपयोग क्यों नहीं RAISERROR?
स्लार्टिडन

4
क्योंकि अन्यथा आप पूरे इंतजार के बाद भी कुछ नहीं देखेंगे। RAISERROR आपको NowAIT विकल्प देता है, इसलिए यह आपको वास्तविक समय में (अनिवार्य रूप से) प्रिंट स्टेटमेंट दिखाएगा, जैसा कि बफर के पूर्ण होने पर या बैच पूरा होने के बाद।
जेरेमी जियाको

0

यहां कमांडटाइमआउट का परीक्षण करने के लिए सी # कोड का एक बहुत ही सरल टुकड़ा है। यह एक नया कमांड बनाता है जो 2 सेकंड तक इंतजार करेगा। कमांडटाइमआउट को 1 सेकंड पर सेट करें और इसे चलाते समय आपको एक अपवाद दिखाई देगा। कमांडटाइमआउट को 0 पर सेट करना या 2 से अधिक कुछ ठीक चलेगा। वैसे, डिफ़ॉल्ट कमांडटाइमआउट 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();
        }
      }
    }
  }
}

2
यदि आप c # में हैं, तो आपको संभवतः Thread.currentThread.sleep (60000) या Thread.sleep (60000) का उपयोग करना चाहिए जो समान कार्य करता है। इस तरह आपकी देरी आपके आवेदन से अलग हो जाती है। इसके बाद अपने बाद के डेटाबेस लॉजिक को कॉल करें।
एक्शन डैन

2
@ActionDan Thread.leep का उपयोग करने से कमांडटाइमआउट का अभ्यास करने में मदद नहीं मिलेगी, हालांकि यह है। एक उदाहरण के रूप में, यह वही करता है जो बॉक्स पर लिखा होता है।
रिचर्ड हैर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.