24:00:00 değerine sahip bir .Net Zaman Aralığı depolamak için doğru SQL türü nedir?


196

TimeSpanSQL Server 2008 R2 bir .Net depolamaya çalışıyorum .

EF Code First Time(7), SQL'de depolanması gerektiğini gösteriyor .

Ancak TimeSpan.Net'te 24 saatten daha uzun süreler kullanılabilir.

TimeSpanSQL sunucusunda .Net depolamanın en iyi yolu nedir ?


15
Yinelenen olayların uzunluğunu depolamak için kullanıyorum. Bu nedenle etkinliğin tarihini bağımsız olarak yakalamak istedim
GraemeMiller


1
İlgili kopya değil. İkisini de yazdım. Birincisi Code First ve TimeSpan için haritayı nasıl değiştireceğinizle ilgili. Diğeri ise gerçek .Net tipi SQL eşlemesi için Timespan.
GraemeMiller

Yanıtlar:


223

Ben veritabanında bir olarak BIGINTdepolamak ve keneler (örn. TimeSpan.Ticks özelliği) sayısını saklamak istiyorum .

Bu şekilde, aldığımda bir TimeSpan nesnesi almak istedim, ben sadece kolay olurdu TimeSpan.FromTicks (değer) yapabilirdi .


3
Sql'deki hesaplamaları nasıl işlersiniz, kaç saat içerdiğini hesaplamanız gerektiğini söyleyebilir misiniz?
Peter

10
Muhtemelen böyle bir zaman nesnesine kene dönüştürmek istiyorum: SELECT CAST(DATEADD(MILLISECOND, @Ticks/CAST(10000 AS BIGINT), '1900-01-01') AS TIME). '1900-01-01'Tarih meselesi, tabii ki, o gerektirdiği sadece üçüncü değişken var gelmez DATEADD(...)fonksiyonu. Bir kene içinde 100 nanosaniye olduğunu unutmayın, ancak kullanırsanız DATEADD(NANOSECOND...taşma olasılığı vardır, bu nedenle milisaniye kullanırsınız. Ayrıca emin olmak için C # kullanarak TimeSpan.TicksPerMillisecond(10000 olmalıdır) bu gerçeği kontrol gerektiğini unutmayın .
Tom Chantler

Bir seçenek dizgi olarak saklanır, daha sonra TimeSpan.Parse (metin) kullanarak yükleyebilirsiniz. boyut açısından veya SQL
sorguları için

65

Tavsiye için teşekkürler. SQL sunucusunda eşdeğer olmadığı için. Basitçe TimeSpan keneler dönüştürülmüş ve DB saklanan bir 2. alan oluşturdu. Daha sonra TimeSpan'ın depolanmasını engelledim

public Int64 ValidityPeriodTicks { get; set; }

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

6
Ayrıca EF Core kullanan herkes için - 2.1'de, değer dönüşümlerini ve TimeSpanToTicksConverter'ı kullanarak veritabanındaki zaman dilimlerini şeffaf bir şekilde kenelerle eşleştirmek için kullanabilirsiniz
GraemeMiller

30

Eğer 24 saatten fazla saklamak yoksa sadece saklayabilir zaman SQL Server 2008 yılından bu yana ve daha sonra haritalama olduğunu

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

Yalnızca 24 saat veya daha kısa bir süre depolamanız gerektiğinde dönüşüm gerekmez.

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

Ancak , 24 saatten fazla saklamak istiyorsanız, keneler halinde saklamanız, verileri almanız ve ardından TimeSpan'a dönüştürmeniz gerekir. Örneğin

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

23
OP'nin dediği gibi, SQL Server'daki "zaman" DataType sadece 24 saate kadar destekliyor,> 24
sa

11
Ayrıca TimeSpan (.NET) negatif olabilirken Time (SQL Server) negatif olabilir.
Edward

11
Bir zaman ve bir süre arasında büyük bir fark vardır. Zaman, belirli bir günün zamanını temsil ederken, süre iki an arasındaki farktır. Bir konum (zaman) ve mesafe (süre) ile karşılaştırın.
Ramon de Klein

3
^ Kesinlikle. - SQL Timetürü bir süreyi değil, DateTime değerinin Time bölümünü temsil eder; için korkunç bir seçim TimeSpan.
BrainSlugs83


7

Bunun eski bir soru olduğunu biliyorum, ancak birkaç başka seçeneğin de belirtildiğinden emin olmak istedim.

TimeSpan'ı bir zaman sql veri türü alanında 24 saatten fazla saklayamadığınız için; diğer birkaç seçenek olabilir.

  1. TimeSpan'ın ToString'ini saklamak için bir varchar (xx) kullanın. Bunun yararı, veri tipine veya hesaplamaya (örneğin milisaniye'ye karşı günler ile günler arası karşı geceler arasında) hassasiyetin pişirilmesi gerekmemesidir. Tek yapmanız gereken TimeSpan.Parse / TryParse kullanmaktır. Ben de öyle yapardım.

  2. İlk tarih + zaman aralığının sonucunu saklayan ikinci bir tarih, datetime veya datetimeoffset kullanın. Db'den okumak TimeSpan x = SecondDate - FirstDate meselesidir. Bu seçeneğin kullanılması, diğer .NET dışı veri erişim kitaplıklarının aynı verilere erişmesini ancak TimeSpans'leri anlamadığını korur; böyle bir ortamın olması durumunda.


1
Seçenek 2, her seferinde işe yarayabilecek gibi geliyor. thx
rahicks

3

Muhtemelen bir zaman aralığı (2 kez veya tarih-saat farkını hesaplayarak) oluşturmanın en olası kaynağı ile tutarlı olmak için, bir .NET'i TimeSpanSQL Server DateTimeTipi olarak saklamak isteyebilirsiniz .

SQL Server, 2 fark nedeni DateTime'(ler Castiçin FloatS' ve daha sonra Castgeri için DateTime) sadece bir olan DateTime1 Ocak 1900 çıkışlı göre. +0,1 saniyelik bir fark 1 Ocak 1900 00: 00: 00.100 ve -0,1 saniyelik bir fark 31 Aralık 1899 23: 59: 59.900 olacaktır.

Bir .NET'i TimeSpanSQL Server DateTimeTürüne dönüştürmek için, önce 1 Ocak 1900'e DateTimeekleyerek bir .NET Türüne dönüştürürsünüz DateTime. Elbette, SQL Server'dan .NET'e okuduğunuzda, önce bir .NET'e okuyun DateTimeve daha sonra bir .NET'e dönüştürmek için 1 Ocak 1900'ü çıkarın TimeSpan.

Zaman aralıklarının SQL Server'lardan DateTimeve SQL Server içinden (yani T-SQL aracılığıyla) oluşturulduğu ve SQL Server'ın 2016'dan önce olduğu, aralık ve hassasiyet gereksinimlerinize bağlı olarak kullanıldığı durumlarda, bunları saklamak pratik olmayabilir Milisaniye olarak (bahsetmemek Ticksgerekirse), çünkü Intdöndürülen Tür DateDiff( BigIntSS 2016 + 'dan gelen DateDiff_Big) ~ 24 gün değerinde milisaniye ve ~ 67 yıl sonra taşar. saniye. Oysa bu çözüm, 0,1 saniyeye kadar ve -147 ila +8,099 yıl arasında hassas bir şekilde zaman aralıklarını ele alacaktır.

UYARILAR:

  1. Bu, yalnızca 1 Ocak 1900 ile ilgili farkın bir SQL Server DateTimeTürü aralığında bir değerle sonuçlanması durumunda işe yarar (1 Ocak 1753 - 31 Aralık 9999 aka -147 ila +8,099 yıl). TimeSpan~ 29 k - +29 k yıl tutabildiğinden , .NET tarafında bu kadar endişelenmemize gerek yok . SQL Server Türünden bahsetmedim DateTime2(aralığı, negatif tarafta, SQL Server'dan çok daha büyüktür DateTime), çünkü: a) basit bir sayıya dönüştürülemez Castve b) DateTimearalığı yeterli olmalıdır kullanım vakalarının büyük çoğunluğu için.

  2. SQL Server DateTimearacılığıyla hesaplanan farklar Castiçin - - Float- - ve geri yöntem 0.1 saniye ötesine doğru görünmüyor.


Bu A'yı yazdığımdan bu Q'yu daha az okuduğumu ve tekrar A'yı aradığımı unuttum. Bu A'yı okumaya başladım ve kendi kendime düşündüm: (Vay be, bu şimdiye kadarki en iyi cevap!). : D
Tom

3

Veritabanında bir zaman aralığı sunmanın birden çok yolu vardır.

zaman

Bu veri türü SQL Server 2008 yılından bu yana desteklenen ve mesafesindedir tercih edilen yöntem bir depolamak için TimeSpan. Haritalamaya gerek yoktur. Ayrıca SQL kodu ile iyi çalışır.

public TimeSpan ValidityPeriod { get; set; }

Bununla birlikte, orijinal soruda belirtildiği gibi, bu veri türü 24 saat ile sınırlıdır.

datetimeoffset

Veri datetimeoffsettürü doğrudan ile eşleşir System.DateTimeOffset. A datetime/ datetime2to UTC arasındaki farkı ifade etmek için kullanılır , ancak bunun için de kullanabilirsiniz TimeSpan.

Ancak, veri türü çok spesifik bir semantik önerdiğinden, diğer seçenekleri de dikkate almalısınız.

datetime / datetime2

Bir yaklaşım datetimeveya datetime2türlerini kullanmak olabilir . Bu, veritabanındaki değerleri doğrudan işlemeniz gereken senaryolarda en iyisidir. görünümler, saklı yordamlar veya raporlar için. Dezavantajı, DateTime(1900,01,01,00,00,00)iş mantığınızdaki zaman aralığını geri almak için tarihten itibaren değeri özetlemeniz gerektiğidir .

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

Başka bir yaklaşım TimeSpan'ı kenelere dönüştürmek ve bigintveri tipini kullanmak olabilir . Ancak, bu yaklaşımın SQL sorgularında kullanmanın zor olduğu dezavantajı vardır.

public long ValidityPeriod { get; set; }

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

varchar (K)

Bu, değerin insanlar tarafından okunabilmesi gereken durumlar için en iyisidir. Bu biçimi, CONVERT(datetime, ValidityPeriod)işlevi kullanarak SQL sorgularında da kullanabilirsiniz . Gerekli hassasiyete bağlı olarak, 8 ila 25 karaktere ihtiyacınız olacaktır.

public string ValidityPeriod { get; set; }

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

Bonus: Süre ve Süre

Bir dize kullanarak, NodaTime veri türlerini, özellikle Durationve Period. Birincisi temelde bir TimeSpan ile aynıdır, daha sonra ise bazı günlerin ve ayların diğerlerinden daha uzun veya daha kısa olduğuna (yani Ocak 31 gün ve Şubat 28 veya 29'a sahiptir; bazı günler yaz saati nedeniyle daha uzun veya daha kısadır) ). Bu gibi durumlarda, TimeSpan kullanmak yanlış seçimdir.

Dönemleri dönüştürmek için bu kodu kullanabilirsiniz:

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)));
    }
}

Ve sonra onu

public string ValidityPeriod { get; set; }

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

Gerçekten hoşuma gidiyor NodaTimeve genellikle beni zor böceklerden ve çok fazla baş ağrısından kurtarıyor. Buradaki dezavantaj, SQL sorgularında gerçekten kullanamamanız ve bellekte hesaplamalar yapmanız gerektiğidir.

CLR Kullanıcı Tanımlı Tip

Ayrıca özel bir veri türü kullanma ve TimeSpandoğrudan özel bir sınıfı destekleme seçeneğiniz de vardır . Ayrıntılar için bkz. CLR Kullanıcı Tanımlı Türler .

Buradaki dezavantaj, veri tipinin SQL Raporları ile iyi davranmayabileceğidir. Ayrıca, SQL Server'ın bazı sürümleri (Azure, Linux, Veri Ambarı) desteklenmez.

Değer Dönüşümleri

EntityFramework Core 2.1 ile başlayarak, Değer Dönüşümlerini kullanma seçeneğiniz vardır .

Ancak, bunu kullanırken, EF birçok sorguyu SQL'e dönüştüremez ve sorguların bellekte çalışmasına neden olur; potansiyel olarak çok ve çok sayıda veriyi uygulamanıza aktarabilirsiniz.

En azından şimdilik, onu kullanmamak daha iyi olabilir ve sorgu sonucunu Automapper ile eşleştirin .


1

Genellikle, bir TimeSpan daha önce önerildiği gibi TimeSpan.Ticks özelliği keneler ile doldurulmuş bir bigint olarak depolamak. TimeSpan'ı, TimeSpan.ToString () çıktısıyla doldurulmuş bir varchar (26) olarak da saklayabilirsiniz. Yazdığım dört skaler fonksiyon (ConvertFromTimeSpanString, ConvertToTimeSpanString, DateAddTicks, DateDiffTicks) SQL tarafında TimeSpan'ı işlemek ve yapay olarak sınırlandırılmış aralıklar üretecek saldırıları önlemek için yararlıdır. Aralığı bir .NET TimeSpan içinde saklayabiliyorsanız, bu işlevlerle de çalışması gerekir. Ayrıca, işlevler .NET Framework içermeyen teknolojileri kullanırken bile TimeSpans ve 100 nanosaniyelik kenelerle çalışmanıza olanak tanır.

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 ---
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.