2011-12-14 35 views
150

Tôi đang cố gắng lưu trữ một .Net TimeSpan trong SQL Server 2008 R2.Loại SQL đúng để lưu trữ một .Net Timespan với các giá trị> 24:00:00 là gì?

Mã EF Đầu tiên dường như cho thấy nó nên được lưu trữ dưới dạng Time(7) trong SQL.

Tuy nhiên TimeSpan trong. Net có thể xử lý thời lượng dài hơn 24 giờ.

Cách tốt nhất để xử lý lưu trữ .Net TimeSpan trong máy chủ SQL là gì?

+0

Tại sao bạn không lưu trữ Current_Date + TimeSpan làm Ngày giờ? Tại sao phức tạp vấn đề này .. Nó sẽ giúp nếu bạn cung cấp thêm thông tin. –

+13

Tôi đang sử dụng nó để lưu trữ độ dài của các sự kiện định kỳ. Vì vậy, tôi muốn nắm bắt độ dài của sự kiện độc lập với ngày – GraemeMiller

+0

bản sao có thể có của [Làm thế nào để tôi ánh xạ TimeSpan với hơn 24 giờ để Mã máy chủ SQL đầu tiên?] (Http://stackoverflow.com/questions/8503132/how -do-i-map-timespan-với-lớn hơn -24-giờ-to-sql-máy chủ-mã-đầu tiên) – 7hi4g0

Trả lời

175

Tôi muốn lưu trữ nó trong cơ sở dữ liệu dưới dạng BIGINT và tôi lưu trữ số lượng bọ ve (ví dụ: TimeSpan.Ticks thuộc tính).

Bằng cách đó, nếu tôi muốn lấy đối tượng TimeSpan khi tôi truy xuất nó, tôi chỉ có thể thực hiện TimeSpan.FromTicks(value) dễ dàng.

+0

Bạn sẽ xử lý như thế nào tính toán trong sql cho phép nói rằng bạn cần phải tính toán bao nhiêu giờ nó chứa? – Peter

+5

Tôi có thể chuyển đổi các con ve thành một đối tượng thời gian như thế này: 'CHỌN CAST (DATEADD (MILLISECOND, @ Ticks/CAST (10000 AS BIGINT), '1900-01-01') AS TIME)'. Ngày '1900-01-01'' không quan trọng, tất nhiên, nó chỉ là biến thứ ba được yêu cầu bởi hàm' DATEADD (...) '. Hãy nhớ rằng có 100 nano giây trong một dấu tích, nhưng nếu bạn sử dụng 'DATEADD (NANOSECOND ...' bạn có khả năng bị tràn, do đó sử dụng mili giây. Cũng nên nhớ rằng bạn nên kiểm tra thực tế này bằng cách sử dụng C# 'TimeSpan.TicksPerMillisecond' (phải là 10000) để chắc chắn –

18

Không có tương đương trực tiếp. Chỉ lưu trữ số lượng, ví dụ: số giây hoặc thứ gì đó phù hợp với độ chính xác yêu cầu của bạn.

+0

tức là. lưu trữ nó dưới dạng float và sử dụng 'TimeSpan.FromSeconds' theo https://msdn.microsoft.com/en-us/library/system.timespan.fromseconds%28v=vs.110%29.aspx –

56

Cảm ơn lời khuyên. Vì không có tương đương trong máy chủ SQL. Tôi chỉ đơn giản là tạo ra một lĩnh vực thứ 2 mà chuyển đổi TimeSpan để đánh dấu và lưu trữ trong DB. sau đó tôi ngăn lưu trữ các đối tượng TimeSpan

public Int64 ValidityPeriodTicks { get; set; } 

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

Nếu bạn không cần phải lưu trữ hơn 24 giờ bạn chỉ có thể lưu trữ thời gian, vì SQL Server 2008 và sau đó là lập bản đồ là

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

Không cần chuyển đổi nếu bạn chỉ cần lưu trữ 24 giờ hoặc ít hơn.

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

Nhưng, nếu bạn muốn lưu trữ nhiều hơn 24h, bạn sẽ cần phải lưu trữ nó trong tích tắc, lấy dữ liệu và sau đó chuyển sang TimeSpan. Ví dụ:

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

Như OP nói, "thời gian" DataType trong SQL Server chỉ hỗ trợ lên đến 24h, ông muốn lưu trữ> 24h – MichelZ

+11

Ngoài ra, TimeSpan (.NET) có thể được tiêu cực trong khi thời gian (SQL Server – Edward

+10

Có sự khác biệt lớn giữa thời gian và thời lượng Thời gian biểu thị thời gian vào một ngày nhất định trong khi thời gian là sự khác biệt giữa hai khoảnh khắc. So sánh nó với một vị trí (thời gian) và khoảng cách (khoảng thời gian) –

6

Tôi biết đây là câu hỏi cũ nhưng tôi muốn đảm bảo một số tùy chọn khác được ghi chú.

Vì bạn không thể lưu trữ một TimeSpan lớn hơn 24 giờ trong một trường dữ liệu sql thời gian; một vài tùy chọn khác có thể là.

  1. Sử dụng varchar (xx) để lưu trữ ToString của TimeSpan. Lợi ích của việc này là độ chính xác không cần phải được đưa vào kiểu dữ liệu hoặc phép tính, (giây so với mili giây so với ngày so với pháo đài) Tất cả những gì bạn cần là sử dụng TimeSpan.Parse/TryParse. Đây là những gì tôi sẽ làm.

  2. Sử dụng ngày thứ hai, datetime hoặc datetimeoffset, lưu trữ kết quả của ngày đầu tiên + khoảng thời gian. Đọc từ db là một vấn đề của TimeSpan x = SecondDate - FirstDate. Sử dụng tùy chọn này sẽ bảo vệ bạn cho các thư viện truy cập dữ liệu không .NET khác truy cập cùng một dữ liệu nhưng không hiểu về TimeSpans; trong trường hợp bạn có một môi trường như vậy.

3

Để phù hợp với những gì có lẽ là nguồn rất có thể tạo ra một khoảng thời gian (tính toán sự khác biệt của 2 lần hoặc ngày-thời gian), bạn có thể muốn lưu trữ một NET TimeSpan như một SQL Server DateTime Kiểu.

Điều này là do trong SQL Server, sự khác biệt của 2 DateTime 's (Cast để Float' s và sau đó Cast trở lại một DateTime) chỉ đơn giản là một DateTime liên quan đến ngày 01 tháng 1, 1900. Ex. Sự khác biệt của +0.1 giây sẽ là ngày 1 tháng 1, 1900 00: 00: 00.100 và -0.1 giây sẽ là ngày 31 tháng 12 năm 1899 23: 59: 59.900.

Để chuyển đổi một NET TimeSpan đến một SQL Server DateTime Loại, trước tiên bạn sẽ chuyển nó sang một NET DateTime Loại bằng cách thêm vào một DateTime của ngày 01 tháng 1, 1900. Tất nhiên, khi bạn đọc nó vào. NET từ SQL Server, trước tiên bạn sẽ đọc nó vào một .NET DateTime và sau đó trừ đi ngày 1 tháng 1 năm 1900 từ nó để chuyển đổi nó thành .NET TimeSpan.

Đối với trường hợp sử dụng khi khoảng thời gian được tạo từ SQL Server DateTime và trong SQL Server (nghĩa là qua T-SQL) và SQL Server trước năm 2016, tùy thuộc vào phạm vi và nhu cầu chính xác của bạn, nó có thể không thực tế để lưu trữ chúng dưới dạng mili giây (chưa kể đến Ticks) vì loại Int được trả lại bởi DateDiff (so với BigInt từ SS 2016 + 'DateDiff_Big) tràn sau ~ 24 ngày trị giá mili giây và ~ 67 yrs. của giây. Trong khi đó, giải pháp này sẽ xử lý thời gian kéo dài với độ chính xác xuống đến 0,1 giây và từ -147 đến 8099 tuổi ..

CẢNH BÁO:

  1. Điều này sẽ chỉ làm việc nếu sự khác biệt so với 01 tháng một, 1900 sẽ dẫn đến một giá trị trong phạm vi của một Máy chủ SQL DateTime Loại (ngày 1 tháng 1 năm 1753 đến ngày 31 tháng 12, 9999 hay còn gọi là -147 đến +8,099 năm). Chúng ta không phải lo lắng nhiều về phía .NET TimeSpan vì nó có thể chứa ~ 29 k đến +29 k yrs. Tôi không đề cập đến Kiểu Máy chủ SQL DateTime2 (có phạm vi, ở phía phủ định, lớn hơn nhiều so với SQL Server DateTime), bởi vì: a) nó không thể được chuyển đổi thành số qua một đơn giản Cast và b) DateTime ' s phạm vi đủ cho phần lớn các trường hợp sử dụng.

  2. Máy chủ SQL DateTime các khác biệt được tính qua phương pháp Cast - to - Float - và - lại không xuất hiện chính xác vượt quá 0,1 giây.

1

Thông thường, tôi lưu trữ một TimeSpan dưới dạng số lượng lớn dấu tick từ thuộc tính TimeSpan.Ticks như đã đề xuất trước đây. Bạn cũng có thể lưu trữ một TimeSpan như là một varchar (26) dân cư với đầu ra của TimeSpan.ToString(). Bốn hàm vô hướng (ConvertFromTimeSpanString, ConvertToTimeSpanString, DateAddTicks, DateDiffTicks) mà tôi đã viết là hữu ích để xử lý TimeSpan ở phía SQL và tránh các hacks có thể tạo ra các dải giới hạn giả tạo. Nếu bạn có thể lưu trữ khoảng thời gian trong một NET TimeSpan ở tất cả, nó cũng nên làm việc với các chức năng này. Ngoài ra, các chức năng cho phép bạn làm việc với các TimeSpans và các ve giây 100 nano giây ngay cả khi sử dụng các công nghệ không bao gồm .NET Framework.

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 --- 
Các vấn đề liên quan