값이 24:00:00 인 .Net Timespan을 저장하는 올바른 SQL 유형은 무엇입니까?


196

TimeSpanSQL Server 2008 R2에 .Net을 저장하려고합니다 .

EF Code First는 Time(7)SQL 로 저장해야한다고 제안하는 것 같습니다 .

그러나 TimeSpan.Net에서는 24 시간보다 긴 기간을 처리 할 수 ​​있습니다.

TimeSpanSQL Server에서 .Net 저장을 처리하는 가장 좋은 방법은 무엇입니까 ?


15
반복 이벤트의 길이를 저장하는 데 사용하고 있습니다. 따라서 날짜와 관계없이 이벤트의 길이를 캡처하고 싶었습니다
GraemeMiller


1
중복되지 않습니다. 나는 둘 다 썼다. 하나는 Code First와 TimeSpan의 맵을 변경하는 방법에 관한 것입니다. 다른 하나는 실제 .Net 유형 Timespan에서 SQL 로의 매핑에 관한 것입니다.
GraemeMiller

답변:


222

데이터베이스에 a로 BIGINT저장하고 틱 수 (예 : TimeSpan.Ticks 속성)를 저장합니다.

그렇게하면 TimeSpan 객체를 검색 할 때 TimeSpan.FromTicks (value) 할 수 있습니다.


3
SQL에서 계산을 어떻게 처리 할 수 ​​있습니까? 포함 된 시간을 계산해야한다고 말합니까?
피터

10
아마도 틱을 다음과 같은 시간 객체로 변환했을 것입니다 SELECT CAST(DATEADD(MILLISECOND, @Ticks/CAST(10000 AS BIGINT), '1900-01-01') AS TIME). '1900-01-01'날짜 문제, 물론, 그것은에 의해 요구되는 단지 세 번째 변수하지 않는 DATEADD(...)기능. 틱에 100 나노초가 있다는 것을 기억하십시오. 그러나 사용 DATEADD(NANOSECOND...하는 경우 오버플로가 발생할 가능성이 있으므로 밀리 초를 사용하십시오. 또한 C # TimeSpan.TicksPerMillisecond(10000이어야 함)을 사용하여이 사실을 확인해야합니다.
Tom Chantler

옵션은 문자열로 저장 한 다음 TimeSpan.Parse (text)를 사용하여로드 할 수 있습니다. 크기 관점이나 SQL 쿼리에서는 이상적이지 않지만 필요한 경우 TSQL에서 구문 분석 할 수 있습니다.
Walter Vehoeven

65

충고 감사합니다. SQL 서버에는 이에 상응하는 것이 없기 때문에. TimeSpan을 틱으로 변환하여 DB에 저장하는 두 번째 필드를 만들었습니다. 그런 다음 TimeSpan을 저장하지 못했습니다.

public Int64 ValidityPeriodTicks { get; set; }

[NotMapped]
public TimeSpan ValidityPeriod
{
    get { return TimeSpan.FromTicks(ValidityPeriodTicks); }
    set { ValidityPeriodTicks = value.Ticks; }
}

6
또한 EF Core를 사용하는 모든 사람에게 2.1에서는 값 변환과 TimeSpanToTicksConverter를 사용하여 데이터베이스의 틱에
타임스 팬을

30

당신이 24 시간 이상을 저장할 수없는 경우 당신은 저장할 수있는 시간을 SQL 서버 2008, 그리고 나중에 매핑입니다

time (SQL Server) <-> TimeSpan(.NET)

24 시간 이하 만 저장하면 전환이 필요하지 않습니다.

출처 : http://msdn.microsoft.com/en-us/library/cc716729(v=vs.110).aspx

그러나 24 시간 이상을 저장하려면 틱에 저장하고 데이터를 검색 한 다음 TimeSpan으로 변환해야합니다. 예를 들어

int timeData = yourContext.yourTable.FirstOrDefault();
TimeSpan ts = TimeSpan.FromMilliseconds(timeData);

23
OP가 말했듯이 SQL Server의 "시간"DataType은 최대 24 시간까지만 지원하며 24 시간 이상을 저장하려고합니다.
MichelZ

11
또한 TimeSpan (.NET)은 음수 일 수 있지만 Time (SQL Server)은 음수 일 수 없습니다.
에드워드

11
시간과 기간 사이에는 큰 차이가 있습니다. 시간은 특정 요일의 시간을 나타내는 반면, 지속 시간은 두 순간의 차이입니다. 위치 (시간) 및 거리 (지속 시간)와 비교하십시오.
Ramon de Klein

3
^ 정확하게. -SQL Time유형은 기간을 나타 내기위한 것이 아니라 DateTime 값의 시간 부분입니다. 에 대한 끔찍한 선택입니다 TimeSpan.
BrainSlugs83


7

나는 이것이 오래된 질문이라는 것을 알고 있지만 몇 가지 다른 옵션을 주목하고 싶었습니다.

24 시간보다 큰 TimeSpan을 시간 SQL 데이터 유형 필드에 저장할 수 없으므로; 다른 몇 가지 옵션이있을 수 있습니다.

  1. varchar (xx)를 사용하여 TimeSpan의 ToString을 저장하십시오. 이것의 장점은 정밀도가 데이터 유형이나 계산에 구워 질 필요가 없다는 것입니다 (초 대 밀리 초 대 일 대 2 박) TimeSpan.Parse / TryParse를 사용하면됩니다. 이것이 내가 할 일입니다.

  2. 첫 번째 날짜 + 시간 범위의 결과를 저장하는 두 번째 날짜, 날짜 시간 또는 날짜 시간 오프셋을 사용하십시오. db에서 읽는 것은 TimeSpan x = SecondDate-FirstDate의 문제입니다. 이 옵션을 사용하면 다른 비 .NET 데이터 액세스 라이브러리가 동일한 데이터에 액세스하지만 TimeSpans를 이해하지 못하도록 보호합니다. 그런 환경이 있다면


1
옵션 2는 가끔 유용 할 것 같은 소리입니다. thx
rahicks

3

시간 범위 (두 번 또는 날짜-시간의 차이를 계산)를 생성 할 가능성이 가장 높은 소스와 일치하도록 .NET TimeSpan을 SQL Server DateTime유형 으로 저장할 수 있습니다 .

SQL 서버 2의 차이 때문이다 DateTime'(들 Cast에 대한 FloatS'후 Cast다시 행 DateTime) 단순히 인 DateTime1 월 1 일 (1900) 예에 대하여. +0.1 초의 차이는 1900 년 1 월 1 일 00 : 00 : 00.100이고 -0.1 초는 1899 년 12 월 31 일 23 : 59 : 59.900입니다.

.NET TimeSpan을 SQL Server DateTime형식으로 변환하려면 먼저 1900 년 1 월 1 일에 .NET DateTime형식을 추가 하여 .NET 형식으로 변환해야합니다. DateTime물론 SQL Server에서 .NET으로 읽을 때는 먼저 .NET으로 읽은 DateTime다음 1900 년 1 월 1 일에서 빼서 .NET 으로 변환하십시오 TimeSpan.

SQL Server DateTime및 SQL Server 내에서 (예 : T-SQL을 통해) 시간 범위가 생성 되고 SQL Server가 2016 년 이전 인 경우, 범위와 정밀도 요구에 따라 저장하는 것이 실용적이지 않을 수 있습니다 ~ 24 일 분의 밀리 초와 ~ 67 세 후에 ( SS 2016+에서 vs 로 반환 된 Ticks) Int유형이 오버플 로 되기 때문에 밀리 초 (분명하지 않음 ) 로 표시됩니다 . 초 반면이 솔루션은 0.1 초에서 -147에서 +8,099 년까지의 정밀도로 시간 범위를 처리합니다.DateDiffBigIntDateDiff_Big

경고 :

  1. 이것은 1900 년 1 월 1 일과의 차이로 인해 SQL Server DateTime유형 (1753 년 1 월 1 일부터 9999 년 12 월 31 일까지 -147에서 +8,099 년) 범위 내의 값이 발생하는 경우에만 작동합니다 . TimeSpan~ 29k에서 + 29kyr까지 수용 할 수 있기 때문에 .NET 측에서는 크게 걱정할 필요가 없습니다 . 나는 a) 단순을 통해 숫자로 변환 할 수 없으며 b) 범위가 충분해야 하기 때문에 SQL Server DateTime2유형에 대해 언급하지 않았습니다 (음수 측면의 범위는 SQL Server보다 훨씬 큽니다 DateTime). 대다수의 유스 케이스.CastDateTime

  2. -에서 -및-뒤로 방법 을 DateTime통해 계산 된 SQL Server 차이 는 0.1 초 이상 정확하지 않은 것으로 보입니다.CastFloat


나는이 A를 쓴 것 보다이 Q를 훨씬 적게 읽었고 A를 다시 찾고 있다는 것을 잊었습니다. 나는이 A를 읽기 시작했고 나 자신에게 생각했다 : (와, 이것이 지금까지 가장 좋은 대답입니다!). : D
Tom

3

데이터베이스에 시간 범위를 표시하는 방법에는 여러 가지가 있습니다.

시각

이 데이터 형식은 SQL Server 2008부터 지원 되며를 저장하는 데 선호되는 방법TimeSpan 입니다. 매핑이 필요하지 않습니다. 또한 SQL 코드와도 잘 작동합니다.

public TimeSpan ValidityPeriod { get; set; }

그러나 원래 질문에 명시된 바와 같이이 데이터 유형은 24 시간으로 제한됩니다.

날짜 시간 오프셋

datetimeoffset데이터 형식에 직접 매핑 System.DateTimeOffset. datetime/ datetime2에서 UTC 사이의 오프셋을 나타내는 데 사용 되지만에 사용할 수도 있습니다 TimeSpan.

그러나 데이터 유형은 매우 구체적인 의미를 제안하므로 다른 옵션도 고려해야합니다.

datetime / datetime2

한 가지 방법은 datetime또는 datetime2유형 을 사용하는 것 입니다. 데이터베이스에서 직접 값을 처리해야하는 시나리오에서 가장 좋습니다. 보기, 저장 프로 시저 또는 보고서 단점은 DateTime(1900,01,01,00,00,00)비즈니스 로직에서 시간 범위를 되찾기 위해 날짜 에서 값을 빼야한다는 것 입니다.

public DateTime ValidityPeriod { get; set; }

[NotMapped]
public TimeSpan ValidityPeriodTimeSpan
{
    get { return ValidityPeriod - DateTime(1900,01,01,00,00,00); }
    set { ValidityPeriod = DateTime(1900,01,01,00,00,00) + value; }
}

bigint

다른 방법은 TimeSpan을 틱으로 변환하고 bigint데이터 유형을 사용하는 것 입니다. 그러나이 방법에는 SQL 쿼리에 사용하기가 번거 롭다는 단점이 있습니다.

public long ValidityPeriod { get; set; }

[NotMapped]
public TimeSpan ValidityPeriodTimeSpan
{
    get { return TimeSpan.FromTicks(ValidityPeriod); }
    set { ValidityPeriod = value.Ticks; }
}

varchar (N)

이것은 사람이 값을 읽을 수 있어야하는 경우에 가장 좋습니다. CONVERT(datetime, ValidityPeriod)함수 를 사용하여 SQL 조회에서이 형식을 사용할 수도 있습니다 . 필요한 정밀도에 따라 8 자에서 25 자 사이가 필요합니다.

public string ValidityPeriod { get; set; }

[NotMapped]
public TimeSpan ValidityPeriodTimeSpan
{
    get { return TimeSpan.Parse(ValidityPeriod); }
    set { ValidityPeriod = value.ToString("HH:mm:ss"); }
}

보너스 : 기간 및 기간

문자열을 사용하여 NodaTime 데이터 유형, 특히 Duration및을 저장할 수도 있습니다 Period. 첫 번째는 기본적으로 TimeSpan과 동일하지만 후자는 일부 일과 월이 다른 날보다 길거나 짧다는 것을 존중합니다 (예 : 1 월은 31 일, 2 월은 28 또는 29 일, 일광 절약 시간으로 인해 일부 날은 길거나 짧음) ). 이러한 경우 TimeSpan을 사용하는 것이 잘못된 선택입니다.

이 코드를 사용하여 기간을 변환 할 수 있습니다.

using NodaTime;
using NodaTime.Serialization.JsonNet;

internal static class PeriodExtensions
{
    public static Period ToPeriod(this string input)
    {
        var js = JsonSerializer.Create(new JsonSerializerSettings());
        js.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
        var quoted = string.Concat(@"""", input, @"""");
        return js.Deserialize<Period>(new JsonTextReader(new StringReader(quoted)));
    }
}

그런 다음 사용하십시오

public string ValidityPeriod { get; set; }

[NotMapped]
public Period ValidityPeriodPeriod
{
    get => ValidityPeriod.ToPeriod();
    set => ValidityPeriod = value.ToString();
}

나는 정말 좋아 NodaTime하고 종종 까다로운 버그와 많은 두통에서 나를 구해줍니다. 여기서 단점은 SQL 쿼리에서 실제로 사용할 수 없으며 메모리 내에서 계산을 수행해야한다는 것입니다.

CLR 사용자 정의 유형

사용자 정의 데이터 유형을 사용하고 사용자 정의 TimeSpan클래스를 직접 지원할 수도 있습니다. 자세한 내용은 CLR 사용자 정의 유형 을 참조하십시오.

여기서 단점은 데이터 유형이 SQL 보고서에서 제대로 작동하지 않을 수 있다는 것입니다. 또한 일부 SQL Server 버전 (Azure, Linux, Data Warehouse)은 지원되지 않습니다.

가치 전환

EntityFramework Core 2.1부터는 값 변환 을 사용할 수있는 옵션이 있습니다 .

그러나 이것을 사용할 때 EF는 많은 쿼리 를 SQL 로 변환 할 수 없으므로 쿼리가 메모리 내에서 실행됩니다. 잠재적으로 많은 양의 데이터를 애플리케이션으로 전송합니다.

적어도 지금까지는 사용하지 않는 것이 좋으며 쿼리 결과를 Automapper로 매핑하는 것이 좋습니다 .


1

일반적으로 TimeSpan을 이전에 제안한대로 TimeSpan.Ticks 속성의 틱으로 채워진 bigint로 저장합니다. TimeSpan을 TimeSpan.ToString ()의 출력으로 채워진 varchar (26)로 저장할 수도 있습니다. 내가 작성한 4 개의 스칼라 함수 (ConvertFromTimeSpanString, ConvertToTimeSpanString, DateAddTicks, DateDiffTicks)는 SQL 측에서 TimeSpan을 처리하는 데 도움이되며 인위적으로 범위가 지정된 해킹을 피합니다. 간격을 .NET TimeSpan에 전혀 저장할 수 있으면 이러한 기능과 함께 작동해야합니다. 또한이 기능을 사용하면 .NET Framework가 포함되지 않은 기술을 사용할 때도 TimeSpan 및 100-nanosecond 틱으로 작업 할 수 있습니다.

DROP FUNCTION [dbo].[DateDiffTicks]
GO

DROP FUNCTION [dbo].[DateAddTicks]
GO

DROP FUNCTION [dbo].[ConvertToTimeSpanString]
GO

DROP FUNCTION [dbo].[ConvertFromTimeSpanString]
GO

SET ANSI_NULLS OFF
GO

SET QUOTED_IDENTIFIER OFF
GO

-- =============================================
-- Author:      James Coe
-- Create date: 2011-05-23
-- Description: Converts from a varchar(26) TimeSpan string to a bigint containing the number of 100 nanosecond ticks.
-- =============================================
/*
    [-][d.]hh:mm:ss[.fffffff] 

    "-" 
     A minus sign, which indicates a negative time interval. No sign is included for a positive time span.

    "d" 
     The number of days in the time interval. This element is omitted if the time interval is less than one day. 

    "hh" 
     The number of hours in the time interval, ranging from 0 to 23. 

    "mm" 
     The number of minutes in the time interval, ranging from 0 to 59. 

    "ss" 
     The number of seconds in the time interval, ranging from 0 to 59. 

    "fffffff" 
     Fractional seconds in the time interval. This element is omitted if the time interval does not include 
     fractional seconds. If present, fractional seconds are always expressed using seven decimal digits.
    */
CREATE FUNCTION [dbo].[ConvertFromTimeSpanString] (@timeSpan varchar(26))
RETURNS bigint
AS
BEGIN
    DECLARE @hourStart int
    DECLARE @minuteStart int
    DECLARE @secondStart int
    DECLARE @ticks bigint
    DECLARE @hours bigint
    DECLARE @minutes bigint
    DECLARE @seconds DECIMAL(9, 7)

    SET @hourStart = CHARINDEX('.', @timeSpan) + 1
    SET @minuteStart = CHARINDEX(':', @timeSpan) + 1
    SET @secondStart = CHARINDEX(':', @timespan, @minuteStart) + 1
    SET @ticks = 0

    IF (@hourStart > 1 AND @hourStart < @minuteStart)
    BEGIN
        SET @ticks = CONVERT(bigint, LEFT(@timespan, @hourstart - 2)) * 864000000000
    END
    ELSE
    BEGIN
        SET @hourStart = 1
    END

    SET @hours = CONVERT(bigint, SUBSTRING(@timespan, @hourStart, @minuteStart - @hourStart - 1))
    SET @minutes = CONVERT(bigint, SUBSTRING(@timespan, @minuteStart, @secondStart - @minuteStart - 1))
    SET @seconds = CONVERT(DECIMAL(9, 7), SUBSTRING(@timespan, @secondStart, LEN(@timeSpan) - @secondStart + 1))

    IF (@ticks < 0)
    BEGIN
        SET @ticks = @ticks - @hours * 36000000000
    END
    ELSE
    BEGIN
        SET @ticks = @ticks + @hours * 36000000000
    END

    IF (@ticks < 0)
    BEGIN
        SET @ticks = @ticks - @minutes * 600000000
    END
    ELSE
    BEGIN
        SET @ticks = @ticks + @minutes * 600000000
    END

    IF (@ticks < 0)
    BEGIN
        SET @ticks = @ticks - @seconds * 10000000.0
    END
    ELSE
    BEGIN
        SET @ticks = @ticks + @seconds * 10000000.0
    END

    RETURN @ticks
END
GO

-- =============================================
-- Author:      James Coe
-- Create date: 2011-05-23
-- Description: Converts from a bigint containing the number of 100 nanosecond ticks to a varchar(26) TimeSpan string.
-- =============================================
/*
[-][d.]hh:mm:ss[.fffffff] 

"-" 
 A minus sign, which indicates a negative time interval. No sign is included for a positive time span.

"d" 
 The number of days in the time interval. This element is omitted if the time interval is less than one day. 

"hh" 
 The number of hours in the time interval, ranging from 0 to 23. 

"mm" 
 The number of minutes in the time interval, ranging from 0 to 59. 

"ss" 
 The number of seconds in the time interval, ranging from 0 to 59. 

"fffffff" 
 Fractional seconds in the time interval. This element is omitted if the time interval does not include 
 fractional seconds. If present, fractional seconds are always expressed using seven decimal digits.
*/
CREATE FUNCTION [dbo].[ConvertToTimeSpanString] (@ticks bigint)
RETURNS varchar(26)
AS
BEGIN
    DECLARE @timeSpanString varchar(26)

    IF (@ticks < 0)
    BEGIN
        SET @timeSpanString = '-'
    END
    ELSE
    BEGIN
        SET @timeSpanString = ''
    END

    -- Days
    DECLARE @days bigint

    SET @days = FLOOR(ABS(@ticks / 864000000000.0))

    IF (@days > 0)
    BEGIN
        SET @timeSpanString = @timeSpanString + CONVERT(varchar(26), @days) + '.'
    END

    SET @ticks = ABS(@ticks % 864000000000)
    -- Hours
    SET @timeSpanString = @timeSpanString + RIGHT('0' + CONVERT(varchar(26), FLOOR(@ticks / 36000000000.0)), 2) + ':'
    SET @ticks = @ticks % 36000000000
    -- Minutes
    SET @timeSpanString = @timeSpanString + RIGHT('0' + CONVERT(varchar(26), FLOOR(@ticks / 600000000.0)), 2) + ':'
    SET @ticks = @ticks % 600000000
    -- Seconds
    SET @timeSpanString = @timeSpanString + RIGHT('0' + CONVERT(varchar(26), FLOOR(@ticks / 10000000.0)), 2)
    SET @ticks = @ticks % 10000000

    -- Fractional Seconds
    IF (@ticks > 0)
    BEGIN
        SET @timeSpanString = @timeSpanString + '.' + LEFT(CONVERT(varchar(26), @ticks) + '0000000', 7)
    END

    RETURN @timeSpanString
END
GO

-- =============================================
-- Author:      James Coe
-- Create date: 2011-05-23
-- Description: Adds the specified number of 100 nanosecond ticks to a date.
-- =============================================
CREATE FUNCTION [dbo].[DateAddTicks] (
    @ticks bigint
    , @starting_date datetimeoffset
    )
RETURNS datetimeoffset
AS
BEGIN
    DECLARE @dateTimeResult datetimeoffset

    IF (@ticks < 0)
    BEGIN
        -- Hours
        SET @dateTimeResult = DATEADD(HOUR, CEILING(@ticks / 36000000000.0), @starting_date)
        SET @ticks = @ticks % 36000000000
        -- Seconds
        SET @dateTimeResult = DATEADD(SECOND, CEILING(@ticks / 10000000.0), @dateTimeResult)
        SET @ticks = @ticks % 10000000
        -- Nanoseconds
        SET @dateTimeResult = DATEADD(NANOSECOND, @ticks * 100, @dateTimeResult)
    END
    ELSE
    BEGIN
        -- Hours
        SET @dateTimeResult = DATEADD(HOUR, FLOOR(@ticks / 36000000000.0), @starting_date)
        SET @ticks = @ticks % 36000000000
        -- Seconds
        SET @dateTimeResult = DATEADD(SECOND, FLOOR(@ticks / 10000000.0), @dateTimeResult)
        SET @ticks = @ticks % 10000000
        -- Nanoseconds
        SET @dateTimeResult = DATEADD(NANOSECOND, @ticks * 100, @dateTimeResult)
    END

    RETURN @dateTimeResult
END
GO

-- =============================================
-- Author:      James Coe
-- Create date: 2011-05-23
-- Description:  Gets the difference between two dates in 100 nanosecond ticks.
-- =============================================
CREATE FUNCTION [dbo].[DateDiffTicks] (
    @starting_date datetimeoffset
    , @ending_date datetimeoffset
    )
RETURNS bigint
AS
BEGIN
    DECLARE @ticks bigint
    DECLARE @days bigint
    DECLARE @hours bigint
    DECLARE @minutes bigint
    DECLARE @seconds bigint

    SET @hours = DATEDIFF(HOUR, @starting_date, @ending_date)
    SET @starting_date = DATEADD(HOUR, @hours, @starting_date)
    SET @ticks = @hours * 36000000000
    SET @seconds = DATEDIFF(SECOND, @starting_date, @ending_date)
    SET @starting_date = DATEADD(SECOND, @seconds, @starting_date)
    SET @ticks = @ticks + @seconds * 10000000
    SET @ticks = @ticks + CONVERT(bigint, DATEDIFF(NANOSECOND, @starting_date, @ending_date)) / 100

    RETURN @ticks
END
GO

--- BEGIN Test Harness ---
SET NOCOUNT ON

DECLARE @dateTimeOffsetMinValue datetimeoffset
DECLARE @dateTimeOffsetMaxValue datetimeoffset
DECLARE @timeSpanMinValueString varchar(26)
DECLARE @timeSpanZeroString varchar(26)
DECLARE @timeSpanMaxValueString varchar(26)
DECLARE @timeSpanMinValueTicks bigint
DECLARE @timeSpanZeroTicks bigint
DECLARE @timeSpanMaxValueTicks bigint
DECLARE @dateTimeOffsetMinMaxDiffTicks bigint
DECLARE @dateTimeOffsetMaxMinDiffTicks bigint

SET @dateTimeOffsetMinValue = '0001-01-01T00:00:00.0000000+00:00'
SET @dateTimeOffsetMaxValue = '9999-12-31T23:59:59.9999999+00:00'
SET @timeSpanMinValueString = '-10675199.02:48:05.4775808'
SET @timeSpanZeroString = '00:00:00'
SET @timeSpanMaxValueString = '10675199.02:48:05.4775807'
SET @timeSpanMinValueTicks = -9223372036854775808
SET @timeSpanZeroTicks = 0
SET @timeSpanMaxValueTicks = 9223372036854775807
SET @dateTimeOffsetMinMaxDiffTicks = 3155378975999999999
SET @dateTimeOffsetMaxMinDiffTicks = -3155378975999999999

-- TimeSpan Conversion Tests
PRINT 'Testing TimeSpan conversions...'

DECLARE @convertToTimeSpanStringMinTicksResult varchar(26)
DECLARE @convertFromTimeSpanStringMinTimeSpanResult bigint
DECLARE @convertToTimeSpanStringZeroTicksResult varchar(26)
DECLARE @convertFromTimeSpanStringZeroTimeSpanResult bigint
DECLARE @convertToTimeSpanStringMaxTicksResult varchar(26)
DECLARE @convertFromTimeSpanStringMaxTimeSpanResult bigint

SET @convertToTimeSpanStringMinTicksResult = dbo.ConvertToTimeSpanString(@timeSpanMinValueTicks)
SET @convertFromTimeSpanStringMinTimeSpanResult = dbo.ConvertFromTimeSpanString(@timeSpanMinValueString)
SET @convertToTimeSpanStringZeroTicksResult = dbo.ConvertToTimeSpanString(@timeSpanZeroTicks)
SET @convertFromTimeSpanStringZeroTimeSpanResult = dbo.ConvertFromTimeSpanString(@timeSpanZeroString)
SET @convertToTimeSpanStringMaxTicksResult = dbo.ConvertToTimeSpanString(@timeSpanMaxValueTicks)
SET @convertFromTimeSpanStringMaxTimeSpanResult = dbo.ConvertFromTimeSpanString(@timeSpanMaxValueString)

-- Test Results
SELECT 'Convert to TimeSpan String from Ticks (Minimum)' AS Test
    , CASE 
        WHEN @convertToTimeSpanStringMinTicksResult = @timeSpanMinValueString
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @timeSpanMinValueTicks AS [Ticks]
    , CONVERT(varchar(26), NULL) AS [TimeSpan String]
    , CONVERT(varchar(26), @convertToTimeSpanStringMinTicksResult) AS [Actual Result]
    , CONVERT(varchar(26), @timeSpanMinValueString) AS [Expected Result]
UNION ALL
SELECT 'Convert from TimeSpan String to Ticks (Minimum)' AS Test
    , CASE 
        WHEN @convertFromTimeSpanStringMinTimeSpanResult = @timeSpanMinValueTicks
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , NULL AS [Ticks]
    , @timeSpanMinValueString AS [TimeSpan String]
    , CONVERT(varchar(26), @convertFromTimeSpanStringMinTimeSpanResult) AS [Actual Result]
    , CONVERT(varchar(26), @timeSpanMinValueTicks) AS [Expected Result]
UNION ALL
SELECT 'Convert to TimeSpan String from Ticks (Zero)' AS Test
    , CASE 
        WHEN @convertToTimeSpanStringZeroTicksResult = @timeSpanZeroString
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @timeSpanZeroTicks AS [Ticks]
    , CONVERT(varchar(26), NULL) AS [TimeSpan String]
    , CONVERT(varchar(26), @convertToTimeSpanStringZeroTicksResult) AS [Actual Result]
    , CONVERT(varchar(26), @timeSpanZeroString) AS [Expected Result]
UNION ALL
SELECT 'Convert from TimeSpan String to Ticks (Zero)' AS Test
    , CASE 
        WHEN @convertFromTimeSpanStringZeroTimeSpanResult = @timeSpanZeroTicks
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , NULL AS [Ticks]
    , @timeSpanZeroString AS [TimeSpan String]
    , CONVERT(varchar(26), @convertFromTimeSpanStringZeroTimeSpanResult) AS [Actual Result]
    , CONVERT(varchar(26), @timeSpanZeroTicks) AS [Expected Result]
UNION ALL
SELECT 'Convert to TimeSpan String from Ticks (Maximum)' AS Test
    , CASE 
        WHEN @convertToTimeSpanStringMaxTicksResult = @timeSpanMaxValueString
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @timeSpanMaxValueTicks AS [Ticks]
    , CONVERT(varchar(26), NULL) AS [TimeSpan String]
    , CONVERT(varchar(26), @convertToTimeSpanStringMaxTicksResult) AS [Actual Result]
    , CONVERT(varchar(26), @timeSpanMaxValueString) AS [Expected Result]
UNION ALL
SELECT 'Convert from TimeSpan String to Ticks (Maximum)' AS Test
    , CASE 
        WHEN @convertFromTimeSpanStringMaxTimeSpanResult = @timeSpanMaxValueTicks
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , NULL AS [Ticks]
    , @timeSpanMaxValueString AS [TimeSpan String]
    , CONVERT(varchar(26), @convertFromTimeSpanStringMaxTimeSpanResult) AS [Actual Result]
    , CONVERT(varchar(26), @timeSpanMaxValueTicks) AS [Expected Result]

-- Ticks Date Add Test
PRINT 'Testing DateAddTicks...'

DECLARE @DateAddTicksPositiveTicksResult datetimeoffset
DECLARE @DateAddTicksZeroTicksResult datetimeoffset
DECLARE @DateAddTicksNegativeTicksResult datetimeoffset

SET @DateAddTicksPositiveTicksResult = dbo.DateAddTicks(@dateTimeOffsetMinMaxDiffTicks, @dateTimeOffsetMinValue)
SET @DateAddTicksZeroTicksResult = dbo.DateAddTicks(@timeSpanZeroTicks, @dateTimeOffsetMinValue)
SET @DateAddTicksNegativeTicksResult = dbo.DateAddTicks(@dateTimeOffsetMaxMinDiffTicks, @dateTimeOffsetMaxValue)

-- Test Results
SELECT 'Date Add with Ticks Test (Positive)' AS Test
    , CASE 
        WHEN @DateAddTicksPositiveTicksResult = @dateTimeOffsetMaxValue
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @dateTimeOffsetMinMaxDiffTicks AS [Ticks]
    , @dateTimeOffsetMinValue AS [Starting Date]
    , @DateAddTicksPositiveTicksResult AS [Actual Result]
    , @dateTimeOffsetMaxValue AS [Expected Result]
UNION ALL
SELECT 'Date Add with Ticks Test (Zero)' AS Test
    , CASE 
        WHEN @DateAddTicksZeroTicksResult = @dateTimeOffsetMinValue
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @timeSpanZeroTicks AS [Ticks]
    , @dateTimeOffsetMinValue AS [Starting Date]
    , @DateAddTicksZeroTicksResult AS [Actual Result]
    , @dateTimeOffsetMinValue AS [Expected Result]
UNION ALL
SELECT 'Date Add with Ticks Test (Negative)' AS Test
    , CASE 
        WHEN @DateAddTicksNegativeTicksResult = @dateTimeOffsetMinValue
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @dateTimeOffsetMaxMinDiffTicks AS [Ticks]
    , @dateTimeOffsetMaxValue AS [Starting Date]
    , @DateAddTicksNegativeTicksResult AS [Actual Result]
    , @dateTimeOffsetMinValue AS [Expected Result]

-- Ticks Date Diff Test
PRINT 'Testing Date Diff Ticks...'

DECLARE @dateDiffTicksMinMaxResult bigint
DECLARE @dateDiffTicksMaxMinResult bigint

SET @dateDiffTicksMinMaxResult = dbo.DateDiffTicks(@dateTimeOffsetMinValue, @dateTimeOffsetMaxValue)
SET @dateDiffTicksMaxMinResult = dbo.DateDiffTicks(@dateTimeOffsetMaxValue, @dateTimeOffsetMinValue)

-- Test Results
SELECT 'Date Difference in Ticks Test (Min, Max)' AS Test
    , CASE 
        WHEN @dateDiffTicksMinMaxResult = @dateTimeOffsetMinMaxDiffTicks
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @dateTimeOffsetMinValue AS [Starting Date]
    , @dateTimeOffsetMaxValue AS [Ending Date]
    , @dateDiffTicksMinMaxResult AS [Actual Result]
    , @dateTimeOffsetMinMaxDiffTicks AS [Expected Result]
UNION ALL
SELECT 'Date Difference in Ticks Test (Max, Min)' AS Test
    , CASE 
        WHEN @dateDiffTicksMaxMinResult = @dateTimeOffsetMaxMinDiffTicks
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @dateTimeOffsetMaxValue AS [Starting Date]
    , @dateTimeOffsetMinValue AS [Ending Date]
    , @dateDiffTicksMaxMinResult AS [Actual Result]
    , @dateTimeOffsetMaxMinDiffTicks AS [Expected Result]

PRINT 'Tests Complete.'
GO
--- END Test Harness ---
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.