WAITFOR DELAY

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Des L. Davis

    WAITFOR DELAY

    System: Dell PowerEdge Server with 3 GB RAM, 2.4 GHz Celeron
    Software: Microsoft SQL Server 2000 Enterprise running on Windows 2003
    Server
    Software: Microsoft SQL Server 2000 Enterprise running on Windows 2000
    Server

    If you run the code below, you'll notice something odd occuring. The
    MilliSecond value does not change after a 1Millisecond delay. Is this a bug
    or am I doing something wrong?
    Any assistance will be greatly appreciated
    ----------------------------------------------------------------------------
    -------
    /*
    Programmer : Des L. Davis
    Date : July 4, 2004
    Purpose : Testing Delayed Reaction
    */

    CREATE PROCEDURE [sp_TestDelay] AS

    DECLARE @DELAYPERIOD NCHAR(12)
    SET @DELAYPERIOD = '00:00:00:001'
    DECLARE @Retries INT
    SET @Retries = 0
    DECLARE @MAXTRIES INT
    SET @MAXTRIES = 1000 -- Maximum number of tries before timing out
    DECLARE @Modified DATETIME

    WHILE ( ( @Retries <= @MAXTRIES ) ) BEGIN

    SET @Modified = GetDate() -- Set Modification Date

    PRINT @Retries
    PRINT @Modified
    PRINT 'Year = ' + CONVERT( NCHAR(4), DATEPART( YEAR, @Modified ) )
    PRINT 'DayOfYear = ' + CONVERT( NCHAR(3), DATEPART( DAYOFYEAR ,
    @Modified ) )
    PRINT 'Hour = ' + CONVERT( NCHAR(2), DATEPART( HOUR, @Modified ) )
    PRINT 'Minute = ' + CONVERT( NCHAR(2), DATEPART( MINUTE, @Modified ) )
    PRINT 'Second = ' + CONVERT( NCHAR(2), DATEPART( SECOND, @Modified ) )
    PRINT 'MilliSecond = ' + CONVERT( NCHAR(3), DATEPART( MILLISECOND,
    @Modified ) )

    SET @Retries = @Retries + 1 -- Increment loop counter and retry

    WAITFOR DELAY @DELAYPERIOD

    END
    GO

    ----------------------------------------------------------------------------
    -------



  • Dan Guzman

    #2
    Re: WAITFOR DELAY

    The SQL Server datetime datatype, and therefore WAITFOR DELAY, is only
    accurate to 3.33 milliseconds and rounding may occur. You can see what is
    happening with the following

    DECLARE @DELAYPERIOD datetime
    SET @DELAYPERIOD = '00:00:00:001'
    SELECT @DELAYPERIOD

    This is documented in the SQL Server 2000 Books Online:

    <Excerpt href="tsqlref.c hm::/ts_da-db_9xut.htm">

    Date and time data from January 1, 1753 through December 31, 9999, to an
    accuracy of one three-hundredth of a second (equivalent to 3.33 milliseconds
    or 0.00333 seconds). Values are rounded to increments of .000, .003, or .007
    seconds, as shown in the table.

    Example Rounded example
    01/01/98 23:59:59.999 1998-01-02 00:00:00.000

    01/01/98 23:59:59.995, 1998-01-01 23:59:59.997
    01/01/98 23:59:59.996,
    01/01/98 23:59:59.997, or
    01/01/98 23:59:59.998

    01/01/98 23:59:59.992, 1998-01-01 23:59:59.993
    01/01/98 23:59:59.993,
    01/01/98 23:59:59.994

    01/01/98 23:59:59.990 or 1998-01-01 23:59:59.990
    01/01/98 23:59:59.991

    </Excerpt>

    --
    Hope this helps.

    Dan Guzman
    SQL Server MVP

    "Des L. Davis" <des.davis@coge co.ca> wrote in message
    news:yq3Gc.3409 9$XY6.2568035@r ead2.cgocable.n et...[color=blue]
    > System: Dell PowerEdge Server with 3 GB RAM, 2.4 GHz Celeron
    > Software: Microsoft SQL Server 2000 Enterprise running on Windows 2003
    > Server
    > Software: Microsoft SQL Server 2000 Enterprise running on Windows 2000
    > Server
    >
    > If you run the code below, you'll notice something odd occuring. The
    > MilliSecond value does not change after a 1Millisecond delay. Is this a[/color]
    bug[color=blue]
    > or am I doing something wrong?
    > Any assistance will be greatly appreciated
    > --------------------------------------------------------------------------[/color]
    --[color=blue]
    > -------
    > /*
    > Programmer : Des L. Davis
    > Date : July 4, 2004
    > Purpose : Testing Delayed Reaction
    > */
    >
    > CREATE PROCEDURE [sp_TestDelay] AS
    >
    > DECLARE @DELAYPERIOD NCHAR(12)
    > SET @DELAYPERIOD = '00:00:00:001'
    > DECLARE @Retries INT
    > SET @Retries = 0
    > DECLARE @MAXTRIES INT
    > SET @MAXTRIES = 1000 -- Maximum number of tries before timing out
    > DECLARE @Modified DATETIME
    >
    > WHILE ( ( @Retries <= @MAXTRIES ) ) BEGIN
    >
    > SET @Modified = GetDate() -- Set Modification Date
    >
    > PRINT @Retries
    > PRINT @Modified
    > PRINT 'Year = ' + CONVERT( NCHAR(4), DATEPART( YEAR, @Modified ) )
    > PRINT 'DayOfYear = ' + CONVERT( NCHAR(3), DATEPART( DAYOFYEAR ,
    > @Modified ) )
    > PRINT 'Hour = ' + CONVERT( NCHAR(2), DATEPART( HOUR, @Modified ) )
    > PRINT 'Minute = ' + CONVERT( NCHAR(2), DATEPART( MINUTE,[/color]
    @Modified ) )[color=blue]
    > PRINT 'Second = ' + CONVERT( NCHAR(2), DATEPART( SECOND, @Modified ) )
    > PRINT 'MilliSecond = ' + CONVERT( NCHAR(3), DATEPART( MILLISECOND,
    > @Modified ) )
    >
    > SET @Retries = @Retries + 1 -- Increment loop counter and retry
    >
    > WAITFOR DELAY @DELAYPERIOD
    >
    > END
    > GO
    >
    > --------------------------------------------------------------------------[/color]
    --[color=blue]
    > -------
    >
    >
    >[/color]


    Comment

    • Aaron W. West

      #3
      Re: WAITFOR DELAY

      I also notice after running a few tests that WAITFOR seems to have a
      resolution of 1/100th second.

      Specifying a delay of '00:00:00:003' causes the same delay as if I'd
      specified 1/100th second.

      WAITFOR DELAY '00:00:00:013' causes a 2/100th second delay (:020 or .02), so
      it apparently always rounds up.

      The behavior seems easier to follow with less output.


      alter PROCEDURE [sp_TestDelay] AS
      DECLARE @DELAYPERIOD DATETIME
      SET @DELAYPERIOD = '00:00:00:013'
      DECLARE @Retries INT
      SET @Retries = 0
      WHILE ( @Retries <= 1000 ) BEGIN
      PRINT DATEPART( MILLISECOND, getdate() )
      SET @Retries = @Retries + 1 -- Increment loop counter and retry
      WAITFOR DELAY @DELAYPERIOD
      END
      GO

      exec sp_testdelay

      577
      597
      617
      637
      657
      .... etc.


      "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
      news:rS4Gc.5251 $R36.1439@newsr ead2.news.pas.e arthlink.net...
      The SQL Server datetime datatype, and therefore WAITFOR DELAY, is only
      accurate to 3.33 milliseconds and rounding may occur. You can see what is
      happening with the following

      DECLARE @DELAYPERIOD datetime
      SET @DELAYPERIOD = '00:00:00:001'
      SELECT @DELAYPERIOD

      This is documented in the SQL Server 2000 Books Online:

      <Excerpt href="tsqlref.c hm::/ts_da-db_9xut.htm">

      Date and time data from January 1, 1753 through December 31, 9999, to an
      accuracy of one three-hundredth of a second (equivalent to 3.33 milliseconds
      or 0.00333 seconds). Values are rounded to increments of .000, .003, or .007
      seconds, as shown in the table.

      Example Rounded example
      01/01/98 23:59:59.999 1998-01-02 00:00:00.000

      01/01/98 23:59:59.995, 1998-01-01 23:59:59.997
      01/01/98 23:59:59.996,
      01/01/98 23:59:59.997, or
      01/01/98 23:59:59.998

      01/01/98 23:59:59.992, 1998-01-01 23:59:59.993
      01/01/98 23:59:59.993,
      01/01/98 23:59:59.994

      01/01/98 23:59:59.990 or 1998-01-01 23:59:59.990
      01/01/98 23:59:59.991

      </Excerpt>

      --
      Hope this helps.

      Dan Guzman
      SQL Server MVP

      "Des L. Davis" <des.davis@coge co.ca> wrote in message
      news:yq3Gc.3409 9$XY6.2568035@r ead2.cgocable.n et...[color=blue]
      > System: Dell PowerEdge Server with 3 GB RAM, 2.4 GHz Celeron
      > Software: Microsoft SQL Server 2000 Enterprise running on Windows 2003
      > Server
      > Software: Microsoft SQL Server 2000 Enterprise running on Windows 2000
      > Server
      >
      > If you run the code below, you'll notice something odd occuring. The
      > MilliSecond value does not change after a 1Millisecond delay. Is this a[/color]
      bug[color=blue]
      > or am I doing something wrong?
      > Any assistance will be greatly appreciated
      > --------------------------------------------------------------------------[/color]
      --[color=blue]
      > -------
      > /*
      > Programmer : Des L. Davis
      > Date : July 4, 2004
      > Purpose : Testing Delayed Reaction
      > */
      >
      > CREATE PROCEDURE [sp_TestDelay] AS
      >
      > DECLARE @DELAYPERIOD NCHAR(12)
      > SET @DELAYPERIOD = '00:00:00:001'
      > DECLARE @Retries INT
      > SET @Retries = 0
      > DECLARE @MAXTRIES INT
      > SET @MAXTRIES = 1000 -- Maximum number of tries before timing out
      > DECLARE @Modified DATETIME
      >
      > WHILE ( ( @Retries <= @MAXTRIES ) ) BEGIN
      >
      > SET @Modified = GetDate() -- Set Modification Date
      >
      > PRINT @Retries
      > PRINT @Modified
      > PRINT 'Year = ' + CONVERT( NCHAR(4), DATEPART( YEAR, @Modified ) )
      > PRINT 'DayOfYear = ' + CONVERT( NCHAR(3), DATEPART( DAYOFYEAR ,
      > @Modified ) )
      > PRINT 'Hour = ' + CONVERT( NCHAR(2), DATEPART( HOUR, @Modified ) )
      > PRINT 'Minute = ' + CONVERT( NCHAR(2), DATEPART( MINUTE,[/color]
      @Modified ) )[color=blue]
      > PRINT 'Second = ' + CONVERT( NCHAR(2), DATEPART( SECOND, @Modified ) )
      > PRINT 'MilliSecond = ' + CONVERT( NCHAR(3), DATEPART( MILLISECOND,
      > @Modified ) )
      >
      > SET @Retries = @Retries + 1 -- Increment loop counter and retry
      >
      > WAITFOR DELAY @DELAYPERIOD
      >
      > END
      > GO
      >
      > --------------------------------------------------------------------------[/color]
      --[color=blue]
      > -------
      >
      >
      >[/color]



      Comment

      • Dan Guzman

        #4
        Re: WAITFOR DELAY

        Standard Windows time API calls are only accurate to about 10 ms and this is
        apparently how SQL Server implements WAITFOR DELAY. When I run a Profiler
        trace, I see statements that run quickly have a reported duration of either
        0 , 13 or 16 milliseconds but nothing in between.

        Below is my test script that shows the actual behavior of WAITFOR DELAY.
        The bottom line is that SQL Server will wait for at least the specified time
        but can wait longer due to the combination of datetime rounding and timer
        interval resolution.

        SET NOCOUNT ON
        IF OBJECT_ID('temp db..#Metrics') IS NOT NULL DROP TABLE #Metrics
        CREATE TABLE #Metrics
        (
        MillisecondDela y int NOT NULL,
        MillisecondDela yTime datetime NOT NULL,
        Retry int NOT NULL,
        StartTime datetime NOT NULL,
        EndTime datetime NOT NULL
        )
        DECLARE @MillisecondDel ay int
        DECLARE @MillisecondDel ayTime datetime
        DECLARE @Retries int
        DECLARE @StartTime datetime
        DECLARE @EndTime datetime

        SET @MillisecondDel ay = 0
        WHILE @MillisecondDel ay < 50
        BEGIN
        SET @MillisecondDel ay = @MillisecondDel ay + 1
        SET @MillisecondDel ayTime = DATEADD(ms, @MillisecondDel ay,
        '00:00:00:000')
        SET @Retries = 0
        WHILE @Retries <= 100
        BEGIN
        SET @Retries = @Retries + 1 -- Increment loop counter and retry
        SET @StartTime = getdate()
        WAITFOR DELAY @MillisecondDel ayTime
        SET @EndTime = getdate()
        INSERT INTO #Metrics VALUES(@Millise condDelay,
        @MillisecondDel ayTime, @Retries, @StartTime, @EndTime)
        END
        END

        SELECT
        MillisecondDela yTime,
        AVG(ActualMilli seconds) AS ActualAverageMi lliseconds
        FROM (
        SELECT
        MillisecondDela yTime,
        DATEDIFF(ms, StartTime, EndTime) AS ActualMilliseco nds
        FROM #Metrics a
        WHERE Retry > 1) AS Metrics
        GROUP BY
        MillisecondDela yTime
        ORDER BY
        MillisecondDela yTime

        --
        Hope this helps.

        Dan Guzman
        SQL Server MVP

        "Aaron W. West" <tallpeak@hotma il.NO.SPAM> wrote in message
        news:E7SdnXfpDs-nl3TdRVn-vw@speakeasy.ne t...[color=blue]
        > I also notice after running a few tests that WAITFOR seems to have a
        > resolution of 1/100th second.
        >
        > Specifying a delay of '00:00:00:003' causes the same delay as if I'd
        > specified 1/100th second.
        >
        > WAITFOR DELAY '00:00:00:013' causes a 2/100th second delay (:020 or .02),[/color]
        so[color=blue]
        > it apparently always rounds up.
        >
        > The behavior seems easier to follow with less output.
        >
        >
        > alter PROCEDURE [sp_TestDelay] AS
        > DECLARE @DELAYPERIOD DATETIME
        > SET @DELAYPERIOD = '00:00:00:013'
        > DECLARE @Retries INT
        > SET @Retries = 0
        > WHILE ( @Retries <= 1000 ) BEGIN
        > PRINT DATEPART( MILLISECOND, getdate() )
        > SET @Retries = @Retries + 1 -- Increment loop counter and retry
        > WAITFOR DELAY @DELAYPERIOD
        > END
        > GO
        >
        > exec sp_testdelay
        >
        > 577
        > 597
        > 617
        > 637
        > 657
        > ... etc.
        >
        >
        > "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
        > news:rS4Gc.5251 $R36.1439@newsr ead2.news.pas.e arthlink.net...
        > The SQL Server datetime datatype, and therefore WAITFOR DELAY, is only
        > accurate to 3.33 milliseconds and rounding may occur. You can see what is
        > happening with the following
        >
        > DECLARE @DELAYPERIOD datetime
        > SET @DELAYPERIOD = '00:00:00:001'
        > SELECT @DELAYPERIOD
        >
        > This is documented in the SQL Server 2000 Books Online:
        >
        > <Excerpt href="tsqlref.c hm::/ts_da-db_9xut.htm">
        >
        > Date and time data from January 1, 1753 through December 31, 9999, to an
        > accuracy of one three-hundredth of a second (equivalent to 3.33[/color]
        milliseconds[color=blue]
        > or 0.00333 seconds). Values are rounded to increments of .000, .003, or[/color]
        ..007[color=blue]
        > seconds, as shown in the table.
        >
        > Example Rounded example
        > 01/01/98 23:59:59.999 1998-01-02 00:00:00.000
        >
        > 01/01/98 23:59:59.995, 1998-01-01 23:59:59.997
        > 01/01/98 23:59:59.996,
        > 01/01/98 23:59:59.997, or
        > 01/01/98 23:59:59.998
        >
        > 01/01/98 23:59:59.992, 1998-01-01 23:59:59.993
        > 01/01/98 23:59:59.993,
        > 01/01/98 23:59:59.994
        >
        > 01/01/98 23:59:59.990 or 1998-01-01 23:59:59.990
        > 01/01/98 23:59:59.991
        >
        > </Excerpt>
        >
        > --
        > Hope this helps.
        >
        > Dan Guzman
        > SQL Server MVP
        >
        > "Des L. Davis" <des.davis@coge co.ca> wrote in message
        > news:yq3Gc.3409 9$XY6.2568035@r ead2.cgocable.n et...[color=green]
        > > System: Dell PowerEdge Server with 3 GB RAM, 2.4 GHz Celeron
        > > Software: Microsoft SQL Server 2000 Enterprise running on Windows 2003
        > > Server
        > > Software: Microsoft SQL Server 2000 Enterprise running on Windows 2000
        > > Server
        > >
        > > If you run the code below, you'll notice something odd occuring. The
        > > MilliSecond value does not change after a 1Millisecond delay. Is this a[/color]
        > bug[color=green]
        > > or am I doing something wrong?
        > > Any assistance will be greatly appreciated[/color]
        >
        > --------------------------------------------------------------------------
        > --[color=green]
        > > -------
        > > /*
        > > Programmer : Des L. Davis
        > > Date : July 4, 2004
        > > Purpose : Testing Delayed Reaction
        > > */
        > >
        > > CREATE PROCEDURE [sp_TestDelay] AS
        > >
        > > DECLARE @DELAYPERIOD NCHAR(12)
        > > SET @DELAYPERIOD = '00:00:00:001'
        > > DECLARE @Retries INT
        > > SET @Retries = 0
        > > DECLARE @MAXTRIES INT
        > > SET @MAXTRIES = 1000 -- Maximum number of tries before timing out
        > > DECLARE @Modified DATETIME
        > >
        > > WHILE ( ( @Retries <= @MAXTRIES ) ) BEGIN
        > >
        > > SET @Modified = GetDate() -- Set Modification Date
        > >
        > > PRINT @Retries
        > > PRINT @Modified
        > > PRINT 'Year = ' + CONVERT( NCHAR(4), DATEPART( YEAR, @Modified ) )
        > > PRINT 'DayOfYear = ' + CONVERT( NCHAR(3), DATEPART( DAYOFYEAR ,
        > > @Modified ) )
        > > PRINT 'Hour = ' + CONVERT( NCHAR(2), DATEPART( HOUR, @Modified ) )
        > > PRINT 'Minute = ' + CONVERT( NCHAR(2), DATEPART( MINUTE,[/color]
        > @Modified ) )[color=green]
        > > PRINT 'Second = ' + CONVERT( NCHAR(2), DATEPART( SECOND,[/color][/color]
        @Modified ) )[color=blue][color=green]
        > > PRINT 'MilliSecond = ' + CONVERT( NCHAR(3), DATEPART( MILLISECOND,
        > > @Modified ) )
        > >
        > > SET @Retries = @Retries + 1 -- Increment loop counter and retry
        > >
        > > WAITFOR DELAY @DELAYPERIOD
        > >
        > > END
        > > GO
        > >[/color]
        >
        > --------------------------------------------------------------------------
        > --[color=green]
        > > -------
        > >
        > >
        > >[/color]
        >
        >
        >[/color]


        Comment

        • Des L. Davis

          #5
          Re: WAITFOR DELAY

          Guys,

          I appreciate the assistance you've all provided. Any suggested work around?

          "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
          news:MhgGc.5715 $R36.1090@newsr ead2.news.pas.e arthlink.net...[color=blue]
          > Standard Windows time API calls are only accurate to about 10 ms and this[/color]
          is[color=blue]
          > apparently how SQL Server implements WAITFOR DELAY. When I run a Profiler
          > trace, I see statements that run quickly have a reported duration of[/color]
          either[color=blue]
          > 0 , 13 or 16 milliseconds but nothing in between.
          >
          > Below is my test script that shows the actual behavior of WAITFOR DELAY.
          > The bottom line is that SQL Server will wait for at least the specified[/color]
          time[color=blue]
          > but can wait longer due to the combination of datetime rounding and timer
          > interval resolution.
          >
          > SET NOCOUNT ON
          > IF OBJECT_ID('temp db..#Metrics') IS NOT NULL DROP TABLE #Metrics
          > CREATE TABLE #Metrics
          > (
          > MillisecondDela y int NOT NULL,
          > MillisecondDela yTime datetime NOT NULL,
          > Retry int NOT NULL,
          > StartTime datetime NOT NULL,
          > EndTime datetime NOT NULL
          > )
          > DECLARE @MillisecondDel ay int
          > DECLARE @MillisecondDel ayTime datetime
          > DECLARE @Retries int
          > DECLARE @StartTime datetime
          > DECLARE @EndTime datetime
          >
          > SET @MillisecondDel ay = 0
          > WHILE @MillisecondDel ay < 50
          > BEGIN
          > SET @MillisecondDel ay = @MillisecondDel ay + 1
          > SET @MillisecondDel ayTime = DATEADD(ms, @MillisecondDel ay,
          > '00:00:00:000')
          > SET @Retries = 0
          > WHILE @Retries <= 100
          > BEGIN
          > SET @Retries = @Retries + 1 -- Increment loop counter and retry
          > SET @StartTime = getdate()
          > WAITFOR DELAY @MillisecondDel ayTime
          > SET @EndTime = getdate()
          > INSERT INTO #Metrics VALUES(@Millise condDelay,
          > @MillisecondDel ayTime, @Retries, @StartTime, @EndTime)
          > END
          > END
          >
          > SELECT
          > MillisecondDela yTime,
          > AVG(ActualMilli seconds) AS ActualAverageMi lliseconds
          > FROM (
          > SELECT
          > MillisecondDela yTime,
          > DATEDIFF(ms, StartTime, EndTime) AS ActualMilliseco nds
          > FROM #Metrics a
          > WHERE Retry > 1) AS Metrics
          > GROUP BY
          > MillisecondDela yTime
          > ORDER BY
          > MillisecondDela yTime
          >
          > --
          > Hope this helps.
          >
          > Dan Guzman
          > SQL Server MVP
          >
          > "Aaron W. West" <tallpeak@hotma il.NO.SPAM> wrote in message
          > news:E7SdnXfpDs-nl3TdRVn-vw@speakeasy.ne t...[color=green]
          > > I also notice after running a few tests that WAITFOR seems to have a
          > > resolution of 1/100th second.
          > >
          > > Specifying a delay of '00:00:00:003' causes the same delay as if I'd
          > > specified 1/100th second.
          > >
          > > WAITFOR DELAY '00:00:00:013' causes a 2/100th second delay (:020 or[/color][/color]
          ..02),[color=blue]
          > so[color=green]
          > > it apparently always rounds up.
          > >
          > > The behavior seems easier to follow with less output.
          > >
          > >
          > > alter PROCEDURE [sp_TestDelay] AS
          > > DECLARE @DELAYPERIOD DATETIME
          > > SET @DELAYPERIOD = '00:00:00:013'
          > > DECLARE @Retries INT
          > > SET @Retries = 0
          > > WHILE ( @Retries <= 1000 ) BEGIN
          > > PRINT DATEPART( MILLISECOND, getdate() )
          > > SET @Retries = @Retries + 1 -- Increment loop counter and retry
          > > WAITFOR DELAY @DELAYPERIOD
          > > END
          > > GO
          > >
          > > exec sp_testdelay
          > >
          > > 577
          > > 597
          > > 617
          > > 637
          > > 657
          > > ... etc.
          > >
          > >
          > > "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
          > > news:rS4Gc.5251 $R36.1439@newsr ead2.news.pas.e arthlink.net...
          > > The SQL Server datetime datatype, and therefore WAITFOR DELAY, is only
          > > accurate to 3.33 milliseconds and rounding may occur. You can see what[/color][/color]
          is[color=blue][color=green]
          > > happening with the following
          > >
          > > DECLARE @DELAYPERIOD datetime
          > > SET @DELAYPERIOD = '00:00:00:001'
          > > SELECT @DELAYPERIOD
          > >
          > > This is documented in the SQL Server 2000 Books Online:
          > >
          > > <Excerpt href="tsqlref.c hm::/ts_da-db_9xut.htm">
          > >
          > > Date and time data from January 1, 1753 through December 31, 9999, to an
          > > accuracy of one three-hundredth of a second (equivalent to 3.33[/color]
          > milliseconds[color=green]
          > > or 0.00333 seconds). Values are rounded to increments of .000, .003, or[/color]
          > .007[color=green]
          > > seconds, as shown in the table.
          > >
          > > Example Rounded example
          > > 01/01/98 23:59:59.999 1998-01-02 00:00:00.000
          > >
          > > 01/01/98 23:59:59.995, 1998-01-01 23:59:59.997
          > > 01/01/98 23:59:59.996,
          > > 01/01/98 23:59:59.997, or
          > > 01/01/98 23:59:59.998
          > >
          > > 01/01/98 23:59:59.992, 1998-01-01 23:59:59.993
          > > 01/01/98 23:59:59.993,
          > > 01/01/98 23:59:59.994
          > >
          > > 01/01/98 23:59:59.990 or 1998-01-01 23:59:59.990
          > > 01/01/98 23:59:59.991
          > >
          > > </Excerpt>
          > >
          > > --
          > > Hope this helps.
          > >
          > > Dan Guzman
          > > SQL Server MVP
          > >
          > > "Des L. Davis" <des.davis@coge co.ca> wrote in message
          > > news:yq3Gc.3409 9$XY6.2568035@r ead2.cgocable.n et...[color=darkred]
          > > > System: Dell PowerEdge Server with 3 GB RAM, 2.4 GHz Celeron
          > > > Software: Microsoft SQL Server 2000 Enterprise running on Windows 2003
          > > > Server
          > > > Software: Microsoft SQL Server 2000 Enterprise running on Windows 2000
          > > > Server
          > > >
          > > > If you run the code below, you'll notice something odd occuring. The
          > > > MilliSecond value does not change after a 1Millisecond delay. Is this[/color][/color][/color]
          a[color=blue][color=green]
          > > bug[color=darkred]
          > > > or am I doing something wrong?
          > > > Any assistance will be greatly appreciated[/color]
          > >[/color]
          >
          > --------------------------------------------------------------------------[color=green]
          > > --[color=darkred]
          > > > -------
          > > > /*
          > > > Programmer : Des L. Davis
          > > > Date : July 4, 2004
          > > > Purpose : Testing Delayed Reaction
          > > > */
          > > >
          > > > CREATE PROCEDURE [sp_TestDelay] AS
          > > >
          > > > DECLARE @DELAYPERIOD NCHAR(12)
          > > > SET @DELAYPERIOD = '00:00:00:001'
          > > > DECLARE @Retries INT
          > > > SET @Retries = 0
          > > > DECLARE @MAXTRIES INT
          > > > SET @MAXTRIES = 1000 -- Maximum number of tries before timing out
          > > > DECLARE @Modified DATETIME
          > > >
          > > > WHILE ( ( @Retries <= @MAXTRIES ) ) BEGIN
          > > >
          > > > SET @Modified = GetDate() -- Set Modification Date
          > > >
          > > > PRINT @Retries
          > > > PRINT @Modified
          > > > PRINT 'Year = ' + CONVERT( NCHAR(4), DATEPART( YEAR,[/color][/color][/color]
          @Modified ) )[color=blue][color=green][color=darkred]
          > > > PRINT 'DayOfYear = ' + CONVERT( NCHAR(3), DATEPART( DAYOFYEAR ,
          > > > @Modified ) )
          > > > PRINT 'Hour = ' + CONVERT( NCHAR(2), DATEPART( HOUR,[/color][/color][/color]
          @Modified ) )[color=blue][color=green][color=darkred]
          > > > PRINT 'Minute = ' + CONVERT( NCHAR(2), DATEPART( MINUTE,[/color]
          > > @Modified ) )[color=darkred]
          > > > PRINT 'Second = ' + CONVERT( NCHAR(2), DATEPART( SECOND,[/color][/color]
          > @Modified ) )[color=green][color=darkred]
          > > > PRINT 'MilliSecond = ' + CONVERT( NCHAR(3), DATEPART([/color][/color][/color]
          MILLISECOND,[color=blue][color=green][color=darkred]
          > > > @Modified ) )
          > > >
          > > > SET @Retries = @Retries + 1 -- Increment loop counter and retry
          > > >
          > > > WAITFOR DELAY @DELAYPERIOD
          > > >
          > > > END
          > > > GO
          > > >[/color]
          > >[/color]
          >
          > --------------------------------------------------------------------------[color=green]
          > > --[color=darkred]
          > > > -------
          > > >
          > > >
          > > >[/color]
          > >
          > >
          > >[/color]
          >
          >[/color]


          Comment

          • Erland Sommarskog

            #6
            Re: WAITFOR DELAY

            Des L. Davis (des.davis@coge co.ca) writes:[color=blue]
            > I appreciate the assistance you've all provided. Any suggested work
            > around?[/color]

            Maybe. If you tell us what the actual business problem you are trying
            to solve, we might come up with something. Trying to run a waitfor in
            only 1 ms, when there is a 10 ms accuracy sounds like a dead end to me.

            OK, so you could write an extended stored procedure to do the waiting,
            but if the Windows API only gives you 10 ms, you would have to roll your
            own, which does not sound trivial to me.



            --
            Erland Sommarskog, SQL Server MVP, esquel@sommarsk og.se

            Books Online for SQL Server SP3 at
            Accelerate your AI application's time to market by harnessing the power of your own data and the built-in AI capabilities of SQL Server 2025, the enterprise database with best-in-class security, performance and availability.

            Comment

            • Dan Guzman

              #7
              Re: WAITFOR DELAY

              Erland's extended proc idea is interesting but, in addition the complexity,
              there may be some overhead involved. Perhaps you can describe the business
              problem. Perhaps there are better methods besides SQL.

              --
              Hope this helps.

              Dan Guzman
              SQL Server MVP

              "Des L. Davis" <des.davis@coge co.ca> wrote in message
              news:bHiGc.3674 0$_V4.19756@rea d1.cgocable.net ...[color=blue]
              > Guys,
              >
              > I appreciate the assistance you've all provided. Any suggested work[/color]
              around?[color=blue]
              >
              > "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
              > news:MhgGc.5715 $R36.1090@newsr ead2.news.pas.e arthlink.net...[color=green]
              > > Standard Windows time API calls are only accurate to about 10 ms and[/color][/color]
              this[color=blue]
              > is[color=green]
              > > apparently how SQL Server implements WAITFOR DELAY. When I run a[/color][/color]
              Profiler[color=blue][color=green]
              > > trace, I see statements that run quickly have a reported duration of[/color]
              > either[color=green]
              > > 0 , 13 or 16 milliseconds but nothing in between.
              > >
              > > Below is my test script that shows the actual behavior of WAITFOR DELAY.
              > > The bottom line is that SQL Server will wait for at least the specified[/color]
              > time[color=green]
              > > but can wait longer due to the combination of datetime rounding and[/color][/color]
              timer[color=blue][color=green]
              > > interval resolution.
              > >
              > > SET NOCOUNT ON
              > > IF OBJECT_ID('temp db..#Metrics') IS NOT NULL DROP TABLE #Metrics
              > > CREATE TABLE #Metrics
              > > (
              > > MillisecondDela y int NOT NULL,
              > > MillisecondDela yTime datetime NOT NULL,
              > > Retry int NOT NULL,
              > > StartTime datetime NOT NULL,
              > > EndTime datetime NOT NULL
              > > )
              > > DECLARE @MillisecondDel ay int
              > > DECLARE @MillisecondDel ayTime datetime
              > > DECLARE @Retries int
              > > DECLARE @StartTime datetime
              > > DECLARE @EndTime datetime
              > >
              > > SET @MillisecondDel ay = 0
              > > WHILE @MillisecondDel ay < 50
              > > BEGIN
              > > SET @MillisecondDel ay = @MillisecondDel ay + 1
              > > SET @MillisecondDel ayTime = DATEADD(ms, @MillisecondDel ay,
              > > '00:00:00:000')
              > > SET @Retries = 0
              > > WHILE @Retries <= 100
              > > BEGIN
              > > SET @Retries = @Retries + 1 -- Increment loop counter and[/color][/color]
              retry[color=blue][color=green]
              > > SET @StartTime = getdate()
              > > WAITFOR DELAY @MillisecondDel ayTime
              > > SET @EndTime = getdate()
              > > INSERT INTO #Metrics VALUES(@Millise condDelay,
              > > @MillisecondDel ayTime, @Retries, @StartTime, @EndTime)
              > > END
              > > END
              > >
              > > SELECT
              > > MillisecondDela yTime,
              > > AVG(ActualMilli seconds) AS ActualAverageMi lliseconds
              > > FROM (
              > > SELECT
              > > MillisecondDela yTime,
              > > DATEDIFF(ms, StartTime, EndTime) AS ActualMilliseco nds
              > > FROM #Metrics a
              > > WHERE Retry > 1) AS Metrics
              > > GROUP BY
              > > MillisecondDela yTime
              > > ORDER BY
              > > MillisecondDela yTime
              > >
              > > --
              > > Hope this helps.
              > >
              > > Dan Guzman
              > > SQL Server MVP
              > >
              > > "Aaron W. West" <tallpeak@hotma il.NO.SPAM> wrote in message
              > > news:E7SdnXfpDs-nl3TdRVn-vw@speakeasy.ne t...[color=darkred]
              > > > I also notice after running a few tests that WAITFOR seems to have a
              > > > resolution of 1/100th second.
              > > >
              > > > Specifying a delay of '00:00:00:003' causes the same delay as if I'd
              > > > specified 1/100th second.
              > > >
              > > > WAITFOR DELAY '00:00:00:013' causes a 2/100th second delay (:020 or[/color][/color]
              > .02),[color=green]
              > > so[color=darkred]
              > > > it apparently always rounds up.
              > > >
              > > > The behavior seems easier to follow with less output.
              > > >
              > > >
              > > > alter PROCEDURE [sp_TestDelay] AS
              > > > DECLARE @DELAYPERIOD DATETIME
              > > > SET @DELAYPERIOD = '00:00:00:013'
              > > > DECLARE @Retries INT
              > > > SET @Retries = 0
              > > > WHILE ( @Retries <= 1000 ) BEGIN
              > > > PRINT DATEPART( MILLISECOND, getdate() )
              > > > SET @Retries = @Retries + 1 -- Increment loop counter and retry
              > > > WAITFOR DELAY @DELAYPERIOD
              > > > END
              > > > GO
              > > >
              > > > exec sp_testdelay
              > > >
              > > > 577
              > > > 597
              > > > 617
              > > > 637
              > > > 657
              > > > ... etc.
              > > >
              > > >
              > > > "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
              > > > news:rS4Gc.5251 $R36.1439@newsr ead2.news.pas.e arthlink.net...
              > > > The SQL Server datetime datatype, and therefore WAITFOR DELAY, is only
              > > > accurate to 3.33 milliseconds and rounding may occur. You can see[/color][/color][/color]
              what[color=blue]
              > is[color=green][color=darkred]
              > > > happening with the following
              > > >
              > > > DECLARE @DELAYPERIOD datetime
              > > > SET @DELAYPERIOD = '00:00:00:001'
              > > > SELECT @DELAYPERIOD
              > > >
              > > > This is documented in the SQL Server 2000 Books Online:
              > > >
              > > > <Excerpt href="tsqlref.c hm::/ts_da-db_9xut.htm">
              > > >
              > > > Date and time data from January 1, 1753 through December 31, 9999, to[/color][/color][/color]
              an[color=blue][color=green][color=darkred]
              > > > accuracy of one three-hundredth of a second (equivalent to 3.33[/color]
              > > milliseconds[color=darkred]
              > > > or 0.00333 seconds). Values are rounded to increments of .000, .003,[/color][/color][/color]
              or[color=blue][color=green]
              > > .007[color=darkred]
              > > > seconds, as shown in the table.
              > > >
              > > > Example Rounded example
              > > > 01/01/98 23:59:59.999 1998-01-02 00:00:00.000
              > > >
              > > > 01/01/98 23:59:59.995, 1998-01-01 23:59:59.997
              > > > 01/01/98 23:59:59.996,
              > > > 01/01/98 23:59:59.997, or
              > > > 01/01/98 23:59:59.998
              > > >
              > > > 01/01/98 23:59:59.992, 1998-01-01 23:59:59.993
              > > > 01/01/98 23:59:59.993,
              > > > 01/01/98 23:59:59.994
              > > >
              > > > 01/01/98 23:59:59.990 or 1998-01-01 23:59:59.990
              > > > 01/01/98 23:59:59.991
              > > >
              > > > </Excerpt>
              > > >
              > > > --
              > > > Hope this helps.
              > > >
              > > > Dan Guzman
              > > > SQL Server MVP
              > > >
              > > > "Des L. Davis" <des.davis@coge co.ca> wrote in message
              > > > news:yq3Gc.3409 9$XY6.2568035@r ead2.cgocable.n et...
              > > > > System: Dell PowerEdge Server with 3 GB RAM, 2.4 GHz Celeron
              > > > > Software: Microsoft SQL Server 2000 Enterprise running on Windows[/color][/color][/color]
              2003[color=blue][color=green][color=darkred]
              > > > > Server
              > > > > Software: Microsoft SQL Server 2000 Enterprise running on Windows[/color][/color][/color]
              2000[color=blue][color=green][color=darkred]
              > > > > Server
              > > > >
              > > > > If you run the code below, you'll notice something odd occuring.[/color][/color][/color]
              The[color=blue][color=green][color=darkred]
              > > > > MilliSecond value does not change after a 1Millisecond delay. Is[/color][/color][/color]
              this[color=blue]
              > a[color=green][color=darkred]
              > > > bug
              > > > > or am I doing something wrong?
              > > > > Any assistance will be greatly appreciated
              > > >[/color]
              > >[/color]
              >
              > --------------------------------------------------------------------------[color=green][color=darkred]
              > > > --
              > > > > -------
              > > > > /*
              > > > > Programmer : Des L. Davis
              > > > > Date : July 4, 2004
              > > > > Purpose : Testing Delayed Reaction
              > > > > */
              > > > >
              > > > > CREATE PROCEDURE [sp_TestDelay] AS
              > > > >
              > > > > DECLARE @DELAYPERIOD NCHAR(12)
              > > > > SET @DELAYPERIOD = '00:00:00:001'
              > > > > DECLARE @Retries INT
              > > > > SET @Retries = 0
              > > > > DECLARE @MAXTRIES INT
              > > > > SET @MAXTRIES = 1000 -- Maximum number of tries before timing out
              > > > > DECLARE @Modified DATETIME
              > > > >
              > > > > WHILE ( ( @Retries <= @MAXTRIES ) ) BEGIN
              > > > >
              > > > > SET @Modified = GetDate() -- Set Modification Date
              > > > >
              > > > > PRINT @Retries
              > > > > PRINT @Modified
              > > > > PRINT 'Year = ' + CONVERT( NCHAR(4), DATEPART( YEAR,[/color][/color]
              > @Modified ) )[color=green][color=darkred]
              > > > > PRINT 'DayOfYear = ' + CONVERT( NCHAR(3), DATEPART( DAYOFYEAR ,
              > > > > @Modified ) )
              > > > > PRINT 'Hour = ' + CONVERT( NCHAR(2), DATEPART( HOUR,[/color][/color]
              > @Modified ) )[color=green][color=darkred]
              > > > > PRINT 'Minute = ' + CONVERT( NCHAR(2), DATEPART( MINUTE,
              > > > @Modified ) )
              > > > > PRINT 'Second = ' + CONVERT( NCHAR(2), DATEPART( SECOND,[/color]
              > > @Modified ) )[color=darkred]
              > > > > PRINT 'MilliSecond = ' + CONVERT( NCHAR(3), DATEPART([/color][/color]
              > MILLISECOND,[color=green][color=darkred]
              > > > > @Modified ) )
              > > > >
              > > > > SET @Retries = @Retries + 1 -- Increment loop counter and[/color][/color][/color]
              retry[color=blue][color=green][color=darkred]
              > > > >
              > > > > WAITFOR DELAY @DELAYPERIOD
              > > > >
              > > > > END
              > > > > GO
              > > > >
              > > >[/color]
              > >[/color]
              >
              > --------------------------------------------------------------------------[color=green][color=darkred]
              > > > --
              > > > > -------
              > > > >
              > > > >
              > > > >
              > > >
              > > >
              > > >[/color]
              > >
              > >[/color]
              >
              >[/color]


              Comment

              • Greg D. Moore \(Strider\)

                #8
                Re: WAITFOR DELAY


                "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
                news:MjmGc.6046 $R36.5921@newsr ead2.news.pas.e arthlink.net...[color=blue]
                > Erland's extended proc idea is interesting but, in addition the[/color]
                complexity,[color=blue]
                > there may be some overhead involved. Perhaps you can describe the[/color]
                business[color=blue]
                > problem. Perhaps there are better methods besides SQL.[/color]

                Btw, I want to mention the only production use I've seen of this (WAITFOR)
                on our servers is I think bad programming. (i.e. it solved the symptom, but
                I'm not sure it solved the underlying problem.)



                Comment

                • Des L. Davis

                  #9
                  Re: WAITFOR DELAY

                  Here is the scenario:

                  I have several hundred thousand rows of data in a MS Access database that
                  must be imported into SQL Server. I cannot employ a simple import since the
                  underlying table schema in both databases are different. So I wrote a C#
                  import routine to do the dirty work for me. The C# application - which
                  we'll call ImportData.EXE - interacts with a SQL Server 2000 Enterprise
                  server database through stored procs only. One of the procs -
                  sp_SaveImported Data - is responsible for saving the imported data. As part
                  of it's insert routine sp_SaveImported Data generates a timebased PrimaryKey
                  (see the formula below) and tries to insert the data using that PrimaryKey.
                  If the insertion fails because of a duplicate PK (i.e. @@ERROR = 2627)
                  sp_SaveImported Data is instructed to wait 1 millisecond (using WAITFOR
                  DELAY '00:00:00:001') , generate a new PK, and retry the insert operation.
                  This happens in a loop which is aborted after 1000 attempts. Any errors are
                  written to a text file for later reconcilliation .

                  If it all works, the PK should look something like 200418677313430 5 which is
                  the result of the following concatenation

                  PK = dbo. PadLeft ( @Year, '0', 4 ) + dbo.PadLeft ( @DayOfYear, '0', 3 )
                  + dbo. PadLeft ( @MilliSecond, '0', 3 ) + dbo.PadLeft ( @Hour, '0', 2 )
                  + dbo.PadLeft ( @Minute, '0', 2 ) + dbo.PadLeft ( @Second, '0', 2 )

                  where PadLeft is a UDF

                  This allows me to insert a theoritical maximum of 1000 rows of data into the
                  SQL Server every second. Obviously this isn't occuring in practice. BTW
                  this is a non issue on an older system (PIII 667, 1GB) - everything works
                  flawlessly which is why the issue went un-noticed for several weeks.

                  The obvious solution here is to re-work how the keys are generated but I'm
                  attempting to better understand what are my real options.

                  "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
                  news:MjmGc.6046 $R36.5921@newsr ead2.news.pas.e arthlink.net...[color=blue]
                  > Erland's extended proc idea is interesting but, in addition the complexity[/color]
                  ,[color=blue]
                  > there may be some overhead involved. Perhaps you can describe the[/color]
                  business[color=blue]
                  > problem. Perhaps there are better methods besides SQL.
                  >
                  > --
                  > Hope this helps.
                  >
                  > Dan Guzman
                  > SQL Server MVP
                  >
                  > "Des L. Davis" <des.davis@coge co.ca> wrote in message
                  > news:bHiGc.3674 0$_V4.19756@rea d1.cgocable.net ...[color=green]
                  > > Guys,
                  > >
                  > > I appreciate the assistance you've all provided. Any suggested work[/color]
                  > around?[color=green]
                  > >
                  > > "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
                  > > news:MhgGc.5715 $R36.1090@newsr ead2.news.pas.e arthlink.net...[color=darkred]
                  > > > Standard Windows time API calls are only accurate to about 10 ms and[/color][/color]
                  > this[color=green]
                  > > is[color=darkred]
                  > > > apparently how SQL Server implements WAITFOR DELAY. When I run a[/color][/color]
                  > Profiler[color=green][color=darkred]
                  > > > trace, I see statements that run quickly have a reported duration of[/color]
                  > > either[color=darkred]
                  > > > 0 , 13 or 16 milliseconds but nothing in between.
                  > > >
                  > > > Below is my test script that shows the actual behavior of WAITFOR[/color][/color][/color]
                  DELAY.[color=blue][color=green][color=darkred]
                  > > > The bottom line is that SQL Server will wait for at least the[/color][/color][/color]
                  specified[color=blue][color=green]
                  > > time[color=darkred]
                  > > > but can wait longer due to the combination of datetime rounding and[/color][/color]
                  > timer[color=green][color=darkred]
                  > > > interval resolution.
                  > > >
                  > > > SET NOCOUNT ON
                  > > > IF OBJECT_ID('temp db..#Metrics') IS NOT NULL DROP TABLE #Metrics
                  > > > CREATE TABLE #Metrics
                  > > > (
                  > > > MillisecondDela y int NOT NULL,
                  > > > MillisecondDela yTime datetime NOT NULL,
                  > > > Retry int NOT NULL,
                  > > > StartTime datetime NOT NULL,
                  > > > EndTime datetime NOT NULL
                  > > > )
                  > > > DECLARE @MillisecondDel ay int
                  > > > DECLARE @MillisecondDel ayTime datetime
                  > > > DECLARE @Retries int
                  > > > DECLARE @StartTime datetime
                  > > > DECLARE @EndTime datetime
                  > > >
                  > > > SET @MillisecondDel ay = 0
                  > > > WHILE @MillisecondDel ay < 50
                  > > > BEGIN
                  > > > SET @MillisecondDel ay = @MillisecondDel ay + 1
                  > > > SET @MillisecondDel ayTime = DATEADD(ms, @MillisecondDel ay,
                  > > > '00:00:00:000')
                  > > > SET @Retries = 0
                  > > > WHILE @Retries <= 100
                  > > > BEGIN
                  > > > SET @Retries = @Retries + 1 -- Increment loop counter and[/color][/color]
                  > retry[color=green][color=darkred]
                  > > > SET @StartTime = getdate()
                  > > > WAITFOR DELAY @MillisecondDel ayTime
                  > > > SET @EndTime = getdate()
                  > > > INSERT INTO #Metrics VALUES(@Millise condDelay,
                  > > > @MillisecondDel ayTime, @Retries, @StartTime, @EndTime)
                  > > > END
                  > > > END
                  > > >
                  > > > SELECT
                  > > > MillisecondDela yTime,
                  > > > AVG(ActualMilli seconds) AS ActualAverageMi lliseconds
                  > > > FROM (
                  > > > SELECT
                  > > > MillisecondDela yTime,
                  > > > DATEDIFF(ms, StartTime, EndTime) AS ActualMilliseco nds
                  > > > FROM #Metrics a
                  > > > WHERE Retry > 1) AS Metrics
                  > > > GROUP BY
                  > > > MillisecondDela yTime
                  > > > ORDER BY
                  > > > MillisecondDela yTime
                  > > >
                  > > > --
                  > > > Hope this helps.
                  > > >
                  > > > Dan Guzman
                  > > > SQL Server MVP
                  > > >
                  > > > "Aaron W. West" <tallpeak@hotma il.NO.SPAM> wrote in message
                  > > > news:E7SdnXfpDs-nl3TdRVn-vw@speakeasy.ne t...
                  > > > > I also notice after running a few tests that WAITFOR seems to have a
                  > > > > resolution of 1/100th second.
                  > > > >
                  > > > > Specifying a delay of '00:00:00:003' causes the same delay as if I'd
                  > > > > specified 1/100th second.
                  > > > >
                  > > > > WAITFOR DELAY '00:00:00:013' causes a 2/100th second delay (:020 or[/color]
                  > > .02),[color=darkred]
                  > > > so
                  > > > > it apparently always rounds up.
                  > > > >
                  > > > > The behavior seems easier to follow with less output.
                  > > > >
                  > > > >
                  > > > > alter PROCEDURE [sp_TestDelay] AS
                  > > > > DECLARE @DELAYPERIOD DATETIME
                  > > > > SET @DELAYPERIOD = '00:00:00:013'
                  > > > > DECLARE @Retries INT
                  > > > > SET @Retries = 0
                  > > > > WHILE ( @Retries <= 1000 ) BEGIN
                  > > > > PRINT DATEPART( MILLISECOND, getdate() )
                  > > > > SET @Retries = @Retries + 1 -- Increment loop counter and[/color][/color][/color]
                  retry[color=blue][color=green][color=darkred]
                  > > > > WAITFOR DELAY @DELAYPERIOD
                  > > > > END
                  > > > > GO
                  > > > >
                  > > > > exec sp_testdelay
                  > > > >
                  > > > > 577
                  > > > > 597
                  > > > > 617
                  > > > > 637
                  > > > > 657
                  > > > > ... etc.
                  > > > >
                  > > > >
                  > > > > "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
                  > > > > news:rS4Gc.5251 $R36.1439@newsr ead2.news.pas.e arthlink.net...
                  > > > > The SQL Server datetime datatype, and therefore WAITFOR DELAY, is[/color][/color][/color]
                  only[color=blue][color=green][color=darkred]
                  > > > > accurate to 3.33 milliseconds and rounding may occur. You can see[/color][/color]
                  > what[color=green]
                  > > is[color=darkred]
                  > > > > happening with the following
                  > > > >
                  > > > > DECLARE @DELAYPERIOD datetime
                  > > > > SET @DELAYPERIOD = '00:00:00:001'
                  > > > > SELECT @DELAYPERIOD
                  > > > >
                  > > > > This is documented in the SQL Server 2000 Books Online:
                  > > > >
                  > > > > <Excerpt href="tsqlref.c hm::/ts_da-db_9xut.htm">
                  > > > >
                  > > > > Date and time data from January 1, 1753 through December 31, 9999,[/color][/color][/color]
                  to[color=blue]
                  > an[color=green][color=darkred]
                  > > > > accuracy of one three-hundredth of a second (equivalent to 3.33
                  > > > milliseconds
                  > > > > or 0.00333 seconds). Values are rounded to increments of .000, .003,[/color][/color]
                  > or[color=green][color=darkred]
                  > > > .007
                  > > > > seconds, as shown in the table.
                  > > > >
                  > > > > Example Rounded example
                  > > > > 01/01/98 23:59:59.999 1998-01-02 00:00:00.000
                  > > > >
                  > > > > 01/01/98 23:59:59.995, 1998-01-01 23:59:59.997
                  > > > > 01/01/98 23:59:59.996,
                  > > > > 01/01/98 23:59:59.997, or
                  > > > > 01/01/98 23:59:59.998
                  > > > >
                  > > > > 01/01/98 23:59:59.992, 1998-01-01 23:59:59.993
                  > > > > 01/01/98 23:59:59.993,
                  > > > > 01/01/98 23:59:59.994
                  > > > >
                  > > > > 01/01/98 23:59:59.990 or 1998-01-01 23:59:59.990
                  > > > > 01/01/98 23:59:59.991
                  > > > >
                  > > > > </Excerpt>
                  > > > >
                  > > > > --
                  > > > > Hope this helps.
                  > > > >
                  > > > > Dan Guzman
                  > > > > SQL Server MVP
                  > > > >
                  > > > > "Des L. Davis" <des.davis@coge co.ca> wrote in message
                  > > > > news:yq3Gc.3409 9$XY6.2568035@r ead2.cgocable.n et...
                  > > > > > System: Dell PowerEdge Server with 3 GB RAM, 2.4 GHz Celeron
                  > > > > > Software: Microsoft SQL Server 2000 Enterprise running on Windows[/color][/color]
                  > 2003[color=green][color=darkred]
                  > > > > > Server
                  > > > > > Software: Microsoft SQL Server 2000 Enterprise running on Windows[/color][/color]
                  > 2000[color=green][color=darkred]
                  > > > > > Server
                  > > > > >
                  > > > > > If you run the code below, you'll notice something odd occuring.[/color][/color]
                  > The[color=green][color=darkred]
                  > > > > > MilliSecond value does not change after a 1Millisecond delay. Is[/color][/color]
                  > this[color=green]
                  > > a[color=darkred]
                  > > > > bug
                  > > > > > or am I doing something wrong?
                  > > > > > Any assistance will be greatly appreciated
                  > > > >
                  > > >[/color]
                  > >[/color]
                  >
                  > --------------------------------------------------------------------------[color=green][color=darkred]
                  > > > > --
                  > > > > > -------
                  > > > > > /*
                  > > > > > Programmer : Des L. Davis
                  > > > > > Date : July 4, 2004
                  > > > > > Purpose : Testing Delayed Reaction
                  > > > > > */
                  > > > > >
                  > > > > > CREATE PROCEDURE [sp_TestDelay] AS
                  > > > > >
                  > > > > > DECLARE @DELAYPERIOD NCHAR(12)
                  > > > > > SET @DELAYPERIOD = '00:00:00:001'
                  > > > > > DECLARE @Retries INT
                  > > > > > SET @Retries = 0
                  > > > > > DECLARE @MAXTRIES INT
                  > > > > > SET @MAXTRIES = 1000 -- Maximum number of tries before timing[/color][/color][/color]
                  out[color=blue][color=green][color=darkred]
                  > > > > > DECLARE @Modified DATETIME
                  > > > > >
                  > > > > > WHILE ( ( @Retries <= @MAXTRIES ) ) BEGIN
                  > > > > >
                  > > > > > SET @Modified = GetDate() -- Set Modification Date
                  > > > > >
                  > > > > > PRINT @Retries
                  > > > > > PRINT @Modified
                  > > > > > PRINT 'Year = ' + CONVERT( NCHAR(4), DATEPART( YEAR,[/color]
                  > > @Modified ) )[color=darkred]
                  > > > > > PRINT 'DayOfYear = ' + CONVERT( NCHAR(3), DATEPART( DAYOFYEAR[/color][/color][/color]
                  ,[color=blue][color=green][color=darkred]
                  > > > > > @Modified ) )
                  > > > > > PRINT 'Hour = ' + CONVERT( NCHAR(2), DATEPART( HOUR,[/color]
                  > > @Modified ) )[color=darkred]
                  > > > > > PRINT 'Minute = ' + CONVERT( NCHAR(2), DATEPART( MINUTE,
                  > > > > @Modified ) )
                  > > > > > PRINT 'Second = ' + CONVERT( NCHAR(2), DATEPART( SECOND,
                  > > > @Modified ) )
                  > > > > > PRINT 'MilliSecond = ' + CONVERT( NCHAR(3), DATEPART([/color]
                  > > MILLISECOND,[color=darkred]
                  > > > > > @Modified ) )
                  > > > > >
                  > > > > > SET @Retries = @Retries + 1 -- Increment loop counter and[/color][/color]
                  > retry[color=green][color=darkred]
                  > > > > >
                  > > > > > WAITFOR DELAY @DELAYPERIOD
                  > > > > >
                  > > > > > END
                  > > > > > GO
                  > > > > >
                  > > > >
                  > > >[/color]
                  > >[/color]
                  >
                  > --------------------------------------------------------------------------[color=green][color=darkred]
                  > > > > --
                  > > > > > -------
                  > > > > >
                  > > > > >
                  > > > > >
                  > > > >
                  > > > >
                  > > > >
                  > > >
                  > > >[/color]
                  > >
                  > >[/color]
                  >
                  >[/color]


                  Comment

                  • Erland Sommarskog

                    #10
                    Re: WAITFOR DELAY

                    Des L. Davis (des.davis@coge co.ca) writes:[color=blue]
                    > I have several hundred thousand rows of data in a MS Access database
                    > that must be imported into SQL Server. I cannot employ a simple import
                    > since the underlying table schema in both databases are different. So I
                    > wrote a C# import routine to do the dirty work for me. The C#
                    > application - which we'll call ImportData.EXE - interacts with a SQL
                    > Server 2000 Enterprise server database through stored procs only. One
                    > of the procs - sp_SaveImported Data - is responsible for saving the
                    > imported data.[/color]

                    Standard comment: the sp_ prefix is reserved for system procedures and SQL
                    Server will first look for these in master.
                    [color=blue]
                    > If it all works, the PK should look something like 200418677313430 5
                    > which is the result of the following concatenation
                    >
                    >PK = dbo. PadLeft ( @Year, '0', 4 ) + dbo.PadLeft ( @DayOfYear, '0', 3 )
                    >+ dbo. PadLeft ( @MilliSecond, '0', 3 ) + dbo.PadLeft ( @Hour, '0', 2 )
                    >+ dbo.PadLeft ( @Minute, '0', 2 ) + dbo.PadLeft ( @Second, '0', 2 )
                    >
                    > where PadLeft is a UDF
                    >
                    > This allows me to insert a theoritical maximum of 1000 rows of data into
                    > the SQL Server every second.[/color]

                    As you have learnt now, the theoretical maximum is 333 rows, and the actual
                    number probably even lower.
                    [color=blue]
                    > The obvious solution here is to re-work how the keys are generated but I'm
                    > attempting to better understand what are my real options.[/color]

                    It wasn't clear to me why have chosen this scheme and not a plain IDENTITY
                    column.

                    If you for some reason want the keys to be scattered, you could use a
                    uniqueidentifie r column and assigned a value with newid().


                    --
                    Erland Sommarskog, SQL Server MVP, esquel@sommarsk og.se

                    Books Online for SQL Server SP3 at
                    Accelerate your AI application's time to market by harnessing the power of your own data and the built-in AI capabilities of SQL Server 2025, the enterprise database with best-in-class security, performance and availability.

                    Comment

                    • Dan Guzman

                      #11
                      Re: WAITFOR DELAY

                      > The obvious solution here is to re-work how the keys are generated but I'm[color=blue]
                      > attempting to better understand what are my real options.[/color]

                      IMHO, you'll be better off generating a surrogate values using an different
                      algorithm. The IDENTITY approach Erland suggested will perform well,
                      guarantee uniqueness and handle concurrency. I'm interested in knowing why
                      you are deliberately assigning non-sequential values. More often than not,
                      'hot spots' are a good thing in SQL 7 and above due to row-level locking.

                      From your description, it appears there is a cursor loop involved somewhere,
                      although it's unclear to me whether this is in sp_SaveImported Data, another
                      proc or ImportData.EXE. In any case, if you want to keep your existing
                      algorithm, consider replacing the millisecond component with your own
                      sequence number that is initialized whenever the time component changes.
                      The untested Transact-SQL script below illustrates this technique.

                      DECLARE @DateComponent char(7)
                      DECLARE @TimeComponent char(6)
                      DECLARE @LastDateCompon ent char(7)
                      DECLARE @LastTimeCompon ent char(6)
                      DECLARE @PK char(16)
                      DECLARE @Sequence int

                      WHILE --some loop condition
                      BEGIN

                      SET @DateComponent =
                      dbo. PadLeft ( @Year, '0', 4 ) +
                      dbo.PadLeft ( @DayOfYear, '0', 3 )
                      SET @TimeComponent =
                      dbo.PadLeft ( @Hour, '0', 2 ) +
                      dbo.PadLeft ( @Minute, '0', 2 ) +
                      dbo.PadLeft ( @Second, '0', 2 )

                      IF @DateComponent + @TimeComponent <> @LastDateCompon ent +
                      @LastTimeCompon ent
                      BEGIN
                      SET @Sequence = 0
                      SET @LastDateCompon ent = @DateComponent
                      SET @LastTimeCompon ent = @TimeComponent
                      END
                      ELSE
                      BEGIN
                      SET @Sequence = @Sequence + 1
                      END
                      SET @PK =
                      @DateComponent +
                      dbo.PadLeft ( @Sequence, '0', 3 ) +
                      @TimeComponent

                      --other code here
                      END

                      --
                      Hope this helps.

                      Dan Guzman
                      SQL Server MVP


                      Comment

                      • Des L. Davis

                        #12
                        Re: WAITFOR DELAY

                        I'm in the process of re-writing the key generating algorithm to eliminate
                        the WAITFOR DELAY. Thanks for all the valuable input.

                        Dan,

                        The keys appear non-sequential if you consider them numerical values.
                        However, they are sequential if you consider them time-based entities.


                        "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
                        news:aMxGc.6914 $oD3.707@newsre ad1.news.pas.ea rthlink.net...[color=blue][color=green]
                        > > The obvious solution here is to re-work how the keys are generated but[/color][/color]
                        I'm[color=blue][color=green]
                        > > attempting to better understand what are my real options.[/color]
                        >
                        > IMHO, you'll be better off generating a surrogate values using an[/color]
                        different[color=blue]
                        > algorithm. The IDENTITY approach Erland suggested will perform well,
                        > guarantee uniqueness and handle concurrency. I'm interested in knowing[/color]
                        why[color=blue]
                        > you are deliberately assigning non-sequential values. More often than[/color]
                        not,[color=blue]
                        > 'hot spots' are a good thing in SQL 7 and above due to row-level locking.
                        >
                        > From your description, it appears there is a cursor loop involved[/color]
                        somewhere,[color=blue]
                        > although it's unclear to me whether this is in sp_SaveImported Data,[/color]
                        another[color=blue]
                        > proc or ImportData.EXE. In any case, if you want to keep your existing
                        > algorithm, consider replacing the millisecond component with your own
                        > sequence number that is initialized whenever the time component changes.
                        > The untested Transact-SQL script below illustrates this technique.
                        >
                        > DECLARE @DateComponent char(7)
                        > DECLARE @TimeComponent char(6)
                        > DECLARE @LastDateCompon ent char(7)
                        > DECLARE @LastTimeCompon ent char(6)
                        > DECLARE @PK char(16)
                        > DECLARE @Sequence int
                        >
                        > WHILE --some loop condition
                        > BEGIN
                        >
                        > SET @DateComponent =
                        > dbo. PadLeft ( @Year, '0', 4 ) +
                        > dbo.PadLeft ( @DayOfYear, '0', 3 )
                        > SET @TimeComponent =
                        > dbo.PadLeft ( @Hour, '0', 2 ) +
                        > dbo.PadLeft ( @Minute, '0', 2 ) +
                        > dbo.PadLeft ( @Second, '0', 2 )
                        >
                        > IF @DateComponent + @TimeComponent <> @LastDateCompon ent +
                        > @LastTimeCompon ent
                        > BEGIN
                        > SET @Sequence = 0
                        > SET @LastDateCompon ent = @DateComponent
                        > SET @LastTimeCompon ent = @TimeComponent
                        > END
                        > ELSE
                        > BEGIN
                        > SET @Sequence = @Sequence + 1
                        > END
                        > SET @PK =
                        > @DateComponent +
                        > dbo.PadLeft ( @Sequence, '0', 3 ) +
                        > @TimeComponent
                        >
                        > --other code here
                        > END
                        >
                        > --
                        > Hope this helps.
                        >
                        > Dan Guzman
                        > SQL Server MVP
                        >
                        >[/color]


                        Comment

                        • Dan Guzman

                          #13
                          Re: WAITFOR DELAY

                          > The keys appear non-sequential if you consider them numerical values.[color=blue]
                          > However, they are sequential if you consider them time-based entities.[/color]

                          The code snippet in your earlier post is concatenating the millisecond
                          component before the remainder of time. Consequently, sequential time
                          values won't be stored consecutively in the ordered index. This is
                          consideration because it introduces index fragmentation and lessens the
                          effectiveness of index.

                          --
                          Hope this helps.

                          Dan Guzman
                          SQL Server MVP

                          "Des L. Davis" <des.davis@coge co.ca> wrote in message
                          news:D3GGc.3715 2$_V4.33574@rea d1.cgocable.net ...[color=blue]
                          > I'm in the process of re-writing the key generating algorithm to eliminate
                          > the WAITFOR DELAY. Thanks for all the valuable input.
                          >
                          > Dan,
                          >
                          > The keys appear non-sequential if you consider them numerical values.
                          > However, they are sequential if you consider them time-based entities.
                          >
                          >
                          > "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
                          > news:aMxGc.6914 $oD3.707@newsre ad1.news.pas.ea rthlink.net...[color=green][color=darkred]
                          > > > The obvious solution here is to re-work how the keys are generated but[/color][/color]
                          > I'm[color=green][color=darkred]
                          > > > attempting to better understand what are my real options.[/color]
                          > >
                          > > IMHO, you'll be better off generating a surrogate values using an[/color]
                          > different[color=green]
                          > > algorithm. The IDENTITY approach Erland suggested will perform well,
                          > > guarantee uniqueness and handle concurrency. I'm interested in knowing[/color]
                          > why[color=green]
                          > > you are deliberately assigning non-sequential values. More often than[/color]
                          > not,[color=green]
                          > > 'hot spots' are a good thing in SQL 7 and above due to row-level[/color][/color]
                          locking.[color=blue][color=green]
                          > >
                          > > From your description, it appears there is a cursor loop involved[/color]
                          > somewhere,[color=green]
                          > > although it's unclear to me whether this is in sp_SaveImported Data,[/color]
                          > another[color=green]
                          > > proc or ImportData.EXE. In any case, if you want to keep your existing
                          > > algorithm, consider replacing the millisecond component with your own
                          > > sequence number that is initialized whenever the time component changes.
                          > > The untested Transact-SQL script below illustrates this technique.
                          > >
                          > > DECLARE @DateComponent char(7)
                          > > DECLARE @TimeComponent char(6)
                          > > DECLARE @LastDateCompon ent char(7)
                          > > DECLARE @LastTimeCompon ent char(6)
                          > > DECLARE @PK char(16)
                          > > DECLARE @Sequence int
                          > >
                          > > WHILE --some loop condition
                          > > BEGIN
                          > >
                          > > SET @DateComponent =
                          > > dbo. PadLeft ( @Year, '0', 4 ) +
                          > > dbo.PadLeft ( @DayOfYear, '0', 3 )
                          > > SET @TimeComponent =
                          > > dbo.PadLeft ( @Hour, '0', 2 ) +
                          > > dbo.PadLeft ( @Minute, '0', 2 ) +
                          > > dbo.PadLeft ( @Second, '0', 2 )
                          > >
                          > > IF @DateComponent + @TimeComponent <> @LastDateCompon ent +
                          > > @LastTimeCompon ent
                          > > BEGIN
                          > > SET @Sequence = 0
                          > > SET @LastDateCompon ent = @DateComponent
                          > > SET @LastTimeCompon ent = @TimeComponent
                          > > END
                          > > ELSE
                          > > BEGIN
                          > > SET @Sequence = @Sequence + 1
                          > > END
                          > > SET @PK =
                          > > @DateComponent +
                          > > dbo.PadLeft ( @Sequence, '0', 3 ) +
                          > > @TimeComponent
                          > >
                          > > --other code here
                          > > END
                          > >
                          > > --
                          > > Hope this helps.
                          > >
                          > > Dan Guzman
                          > > SQL Server MVP
                          > >
                          > >[/color]
                          >
                          >[/color]


                          Comment

                          • Des L. Davis

                            #14
                            Re: WAITFOR DELAY

                            Dan,

                            You've been awesome and I'm very appreciative. Thank you


                            "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
                            news:b2IGc.6989 $R36.4269@newsr ead2.news.pas.e arthlink.net...[color=blue][color=green]
                            > > The keys appear non-sequential if you consider them numerical values.
                            > > However, they are sequential if you consider them time-based entities.[/color]
                            >
                            > The code snippet in your earlier post is concatenating the millisecond
                            > component before the remainder of time. Consequently, sequential time
                            > values won't be stored consecutively in the ordered index. This is
                            > consideration because it introduces index fragmentation and lessens the
                            > effectiveness of index.
                            >
                            > --
                            > Hope this helps.
                            >
                            > Dan Guzman
                            > SQL Server MVP
                            >
                            > "Des L. Davis" <des.davis@coge co.ca> wrote in message
                            > news:D3GGc.3715 2$_V4.33574@rea d1.cgocable.net ...[color=green]
                            > > I'm in the process of re-writing the key generating algorithm to[/color][/color]
                            eliminate[color=blue][color=green]
                            > > the WAITFOR DELAY. Thanks for all the valuable input.
                            > >
                            > > Dan,
                            > >
                            > > The keys appear non-sequential if you consider them numerical values.
                            > > However, they are sequential if you consider them time-based entities.
                            > >
                            > >
                            > > "Dan Guzman" <danguzman@nosp am-earthlink.net> wrote in message
                            > > news:aMxGc.6914 $oD3.707@newsre ad1.news.pas.ea rthlink.net...[color=darkred]
                            > > > > The obvious solution here is to re-work how the keys are generated[/color][/color][/color]
                            but[color=blue][color=green]
                            > > I'm[color=darkred]
                            > > > > attempting to better understand what are my real options.
                            > > >
                            > > > IMHO, you'll be better off generating a surrogate values using an[/color]
                            > > different[color=darkred]
                            > > > algorithm. The IDENTITY approach Erland suggested will perform well,
                            > > > guarantee uniqueness and handle concurrency. I'm interested in[/color][/color][/color]
                            knowing[color=blue][color=green]
                            > > why[color=darkred]
                            > > > you are deliberately assigning non-sequential values. More often than[/color]
                            > > not,[color=darkred]
                            > > > 'hot spots' are a good thing in SQL 7 and above due to row-level[/color][/color]
                            > locking.[color=green][color=darkred]
                            > > >
                            > > > From your description, it appears there is a cursor loop involved[/color]
                            > > somewhere,[color=darkred]
                            > > > although it's unclear to me whether this is in sp_SaveImported Data,[/color]
                            > > another[color=darkred]
                            > > > proc or ImportData.EXE. In any case, if you want to keep your[/color][/color][/color]
                            existing[color=blue][color=green][color=darkred]
                            > > > algorithm, consider replacing the millisecond component with your own
                            > > > sequence number that is initialized whenever the time component[/color][/color][/color]
                            changes.[color=blue][color=green][color=darkred]
                            > > > The untested Transact-SQL script below illustrates this technique.
                            > > >
                            > > > DECLARE @DateComponent char(7)
                            > > > DECLARE @TimeComponent char(6)
                            > > > DECLARE @LastDateCompon ent char(7)
                            > > > DECLARE @LastTimeCompon ent char(6)
                            > > > DECLARE @PK char(16)
                            > > > DECLARE @Sequence int
                            > > >
                            > > > WHILE --some loop condition
                            > > > BEGIN
                            > > >
                            > > > SET @DateComponent =
                            > > > dbo. PadLeft ( @Year, '0', 4 ) +
                            > > > dbo.PadLeft ( @DayOfYear, '0', 3 )
                            > > > SET @TimeComponent =
                            > > > dbo.PadLeft ( @Hour, '0', 2 ) +
                            > > > dbo.PadLeft ( @Minute, '0', 2 ) +
                            > > > dbo.PadLeft ( @Second, '0', 2 )
                            > > >
                            > > > IF @DateComponent + @TimeComponent <> @LastDateCompon ent +
                            > > > @LastTimeCompon ent
                            > > > BEGIN
                            > > > SET @Sequence = 0
                            > > > SET @LastDateCompon ent = @DateComponent
                            > > > SET @LastTimeCompon ent = @TimeComponent
                            > > > END
                            > > > ELSE
                            > > > BEGIN
                            > > > SET @Sequence = @Sequence + 1
                            > > > END
                            > > > SET @PK =
                            > > > @DateComponent +
                            > > > dbo.PadLeft ( @Sequence, '0', 3 ) +
                            > > > @TimeComponent
                            > > >
                            > > > --other code here
                            > > > END
                            > > >
                            > > > --
                            > > > Hope this helps.
                            > > >
                            > > > Dan Guzman
                            > > > SQL Server MVP
                            > > >
                            > > >[/color]
                            > >
                            > >[/color]
                            >
                            >[/color]


                            Comment

                            • Dan Guzman

                              #15
                              Re: WAITFOR DELAY

                              Glad it helped.

                              --
                              Dan Guzman
                              SQL Server MVP


                              Comment

                              Working...