2009-03-05 43 views
8

Lớp .NET TimeZoneInfo là tuyệt vời và tôi nghĩ nó sẽ trả lời tất cả các vấn đề của tôi với việc ghi dữ liệu từ nhiều múi giờ trong cơ sở dữ liệu SQL 2005 của tôi.Thời gian truy cậpZoneInfo từ SQL 2005 Server

Để chuyển đổi ngày giờ UTC trong cơ sở dữ liệu sang bất kỳ múi giờ nào khác, tôi chỉ muốn có múi giờ vào lớp TimeZoneInfo bằng TimeZoneInfo.FindSystemTimeZoneById() và sau đó gọi TimeZoneInfo.ConvertTimeFromUtc(). Rực rỡ! Tôi chỉ gọi nó từ SQL .NET CLR!

NHƯNG ... TimeZoneInfo có Thuộc tính bảo vệ máy chủ lưu trữ của MayLeakOnAbort.

Khi tôi sử dụng VS 2008 để tạo một hàm SQL hoặc thủ tục lưu sẵn, tôi thậm chí không thể nhìn thấy hệ thống.TimeZoneInfo lớp nevermind sử dụng nó. Tôi cũng giả định rằng ngay cả khi tôi có thể tham khảo lớp TimeZoneInfo bằng cách nào đó, tôi có thể sẽ nhận được một số ngoại lệ bảo mật nếu tôi cố đăng ký assembly trong SQL Sever 2005.

Trợ giúp! Có cách nào để truy cập vào lớp TimeZoneInfo và tất cả sự giàu có của nó từ SQL Server 2005?

NB: Tôi vừa thêm thông báo này sau câu trả lời đầu tiên:

Chúng tôi có các trang web tại các địa điểm khác nhau trên khắp thế giới. Chúng tôi cần lưu trữ thời gian địa phương và thời gian UTC trong cơ sở dữ liệu chống lại các sự kiện có thể yêu cầu xu hướng ở cấp Trang web. Một xu hướng có thể bao gồm hơn 52.000 điểm dữ liệu trong một năm, do đó, để có hiệu quả, tôi không thể chỉ lưu trữ thời gian trong UTC trong DB và chuyển đổi mọi điểm dữ liệu trên máy khách. Vì vậy, tôi cần khả năng, trong DB để chuyển đổi một giờ địa phương trong bất kỳ múi giờ nào đến và từ thời gian UTC.

+0

Bạn đang thực sự lưu trữ gì trong cơ sở dữ liệu? Bạn có lưu trữ thực tế là dữ liệu này đã được ghi lại vào lúc 3 giờ chiều ở Pháp hay bạn đang lưu trữ thực tế rằng dữ liệu đó đã được ghi lại lúc 2 giờ chiều theo giờ UTC chưa? Nếu đó là cũ, bạn chỉ có thể lưu trữ bù đắp thời gian địa phương trong một cột –

+0

Tôi cần phải ghi lại cả UTC và giờ địa phương. Báo cáo trang web thường sẽ được yêu cầu trong thời gian địa phương, trang web, báo cáo toàn doanh nghiệp sẽ được yêu cầu trong thời gian UTC. Bất kể, tôi vẫn cần khả năng, ở cấp độ cơ sở dữ liệu, để làm việc ra những gì bù đắp địa phương hoặc thời gian IS! Người dùng nhập có thể ở bất kỳ múi giờ nào. – user74207

Trả lời

1

Tôi không biết liệu bạn có thể truy cập lớp TimeZoneInfo từ SQL hay không, nhưng thường được coi là thực hành tốt để gắn bó với UTC trong cơ sở dữ liệu, với ứng dụng khách dịch sang giờ địa phương.

Vì vậy, mỗi khi bạn ghi vào cơ sở dữ liệu, bạn dịch từ giờ địa phương sang UTC, mỗi khi bạn đọc từ cơ sở dữ liệu, bạn dịch từ UTC sang giờ địa phương.

EDIT: Từ những gì tôi hiểu về vấn đề này, các giải pháp mà tôi vẫn muốn giới thiệu là:

1) Lưu trữ các ngày trong UTC trong cơ sở dữ liệu. 2) Tính giờ địa phương trong ứng dụng khách.

2 có thể được thực hiện theo một số cách. Cách được khuyến nghị là đặt DateTimeMode thành Local (hoặc Utc) trong lớp DataColumn (*). Nếu bạn cần báo cáo theo giờ địa phương, hãy sử dụng Local, nếu bạn cần báo cáo trong UTC, hãy sử dụng UTC.

(*) Xin lưu ý rằng có những vấn đề với các nhà thiết kế trong Visual Studio, xem bài đăng blog: http://bethmassi.blogspot.com/2006/01/serializing-data-across-time-zones-in.html, báo cáo lỗi: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=96118

+0

Cảm ơn M, Không tốt lắm. Tôi cần lưu trữ cả UTC và giờ địa phương trong DB. Chúng tôi có các trang web trên khắp thế giới. Báo cáo trang web, theo mặc định, cần phải ở trong giờ địa phương. Xu hướng trong một năm có thể là 52.000 điểm dữ liệu. Tôi không thể xử lý 52.000 ngày trên máy khách! Tôi cần phải chuyển đổi từ UTC sang địa phương trong DB. – user74207

+0

Giờ địa phương ở đâu? Giờ địa phương nơi báo cáo đang chạy hoặc giờ địa phương nơi dữ liệu được thu thập? –

+0

Theo giờ địa phương, tôi có nghĩa là thời gian tại trang web dữ liệu được ghi lại. Dữ liệu có thể đến từ người dùng hoặc dịch vụ ở các múi giờ khác nhau, do đó, nó không nghiêm ngặt "nơi dữ liệu được thu thập". Ví dụ. nếu người dùng ở Hoa Kỳ ghi lại dữ liệu về một trang web ở Vương quốc Anh, tôi cần dữ liệu được ghi lại theo giờ địa phương của UTC và Vương quốc Anh. – user74207

0

Chúng tôi đã tìm kiếm này trong một thời gian nhưng chưa được có thể tìm ra cách tốt để làm điều đó. Tôi nghĩ rằng đó là trong danh sách những thứ được thêm vào trong SQL 2008 nếu tôi nhớ từ khi nhìn vào nó một lúc trở lại.

+0

Hi Ryan: SQL 2008 có kiểu dữ liệu DATETIMEOFFSET mới có thể phủ nhận nhu cầu của tôi để lưu trữ cả thời gian cục bộ và UTC, nhưng vẫn không có chức năng chuyển đổi múi giờ - chuyển đổi giữa UTC và thời gian máy chủ cục bộ. đang làm việc qua nhiều múi giờ. – user74207

+0

Như tôi đã hiểu, datetimeoffset chỉ là một datetime với thông tin múi giờ được lưu với nó. –

+0

Hi Matthieu - vâng, điều thú vị là nó khớp chính xác với datatype datetimeoffset trong .NET 3.5. Một cách hiệu quả để lưu trữ thời gian địa phương và thời gian UTC trong một trường. Đáng buồn thay, điều này không giúp với vấn đề cụ thể của tôi mặc dù! – user74207

1

Tôi đã gặp phải vấn đề này vì tôi muốn chuyển đổi giữa địa phương và UTC trong truy vấn đang được sử dụng bởi dịch vụ báo cáo. Tôi đã trải qua những gì có vẻ là cùng một cuộc đấu tranh chính xác mà bạn đang trải qua với điều này. Giải pháp của tôi ...

Tôi bắt đầu viết một ứng dụng độc lập đi qua đối tượng TimeZoneInfo và ghi các mục nhập vào bảng TimeZoneInfo trong cơ sở dữ liệu của tôi.Tôi lưu trữ tất cả các offsets (bao gồm cả offsets tiết kiệm ánh sáng ban ngày) cho mỗi năm giữa một năm bắt đầu và kết thúc năm (đây là những đối số cho các ứng dụng độc lập đứng). Từ bảng này, sau đó tôi có thể tạo một số hàm sql sẽ mất một ngày trong utc hoặc cục bộ và múi giờ, sử dụng bảng tra cứu TimeZoneInfo để có được độ lệch phù hợp cho đúng thời điểm trong năm và múi giờ, và trả về datetime được chuyển đổi thành UTC hoặc local.

Thật không may, tôi vẫn chưa hoàn thành. Tôi đã phải tạo một hàm CLR trả về múi giờ hiện tại của hệ thống bằng cách sử dụng một thư viện an toàn cho SQL Server (không giống như đối tượng TimeZoneInfo). Tôi không có quyền truy cập vào mã của mình vào lúc này, nhưng tôi tin rằng tôi đã sử dụng đối tượng TimeZone.

http://msdn.microsoft.com/en-us/library/system.timezone_members.aspx

Nói tóm lại, tôi đã có một chức năng CLR đó quay trở lại múi giờ của hệ thống, một ứng dụng mà tạo ra một múi giờ nhìn lên bảng với DLS thông tin cụ thể cho một loạt các năm. Tôi đứng đầu tất cả với một thủ tục được lưu trữ trong một múi giờ và một ngày để chuyển đổi và nó đã được làm việc đẹp kể từ đó.

Tôi hiểu đây là một công việc HUGE xung quanh để làm một cái gì đó có vẻ khá đơn giản, nhưng nó đã hoàn thành công việc một cách an toàn.

0

Bạn đã xem bài viết này trên Channel9 chưa? Có vẻ như làm những gì bạn đang tìm kiếm trong một chức năng CLR ... mặc dù tôi không nghĩ rằng bạn sẽ nhận được tất cả các goodies bạn muốn truy cập vào ... nhưng nó là một sự khởi đầu.

http://channel9.msdn.com/playground/Sandbox/139123/

Vấn đề rằng một trong những áp phích trên chủ đề đó đề cập đến mặc dù là nó là một hội đồng không an toàn vì p/gọi.

1

Dưới đây là một giải pháp:

  1. Tạo một proc CLR được lưu trữ hoặc UDF, bao bọc các chức năng của lớp TimeZoneInfo. Làm theo hướng dẫn này: http://www.codeproject.com/KB/cs/CLR_Stored_Procedure.aspx
  2. TimeZoneInfo yêu cầu .NET 3.5. Tuy nhiên, System.Core v3.5 sẽ không vượt qua xác minh trong Sql Server 2005. Vì vậy, bạn phải làm một CREATE ASSEMBLY cho System.Core. Xem chi tiết: http://weblogs.asp.net/paulomorgado/archive/2009/06/13/playing-with-sql-server-clr-integration-part-iv-deploying-to-sql-server-2005.aspx

Lưu ý rằng bạn cần phải đăng ký System.Core as UNSAFE ... để bạn có thể gặp vấn đề với DBA.

Hơn nữa, ngay cả khi bạn đã được triển khai để Sql Server 2008 (trong đó bao gồm .NET 3.5), lắp ráp tùy chỉnh của bạn sẽ phải thể không an toàn vì nó sử dụng các phương pháp không an toàn từ TimeZoneInfo: http://social.msdn.microsoft.com/Forums/en/sqlnetfx/thread/d0515862-eb87-4a13-bab4-0e343983823a

tôi đã cố gắng này và nhận được một thông báo liên quan đến MayLeakOnAbort.

Nếu UNSAFE ở trong môi trường của bạn, bạn sẽ có thể thực hiện.

+0

Giải pháp này cũng yêu cầu cơ sở dữ liệu được đặt thành chế độ TRUSTWORTHY, thay vì ký kết các hội đồng. – Suncat2000

3

Tôi vừa hoàn thành việc này trên cơ sở dữ liệu SQL 2008.

Trước tiên, tôi phải đặt DB thành đáng tin cậy và xác minh chủ sở hữu là chính xác.

use [myDB] 
go 
alter database [myDB] set trustworthy on 
go 

exec sp_changedbowner 'sa' 
go 

Tiếp theo, tôi đã tạo a.NET giải pháp

Imports System 
Imports System.Data 
Imports System.Data.SqlClient 
Imports System.Data.SqlTypes 
Imports Microsoft.SqlServer.Server 
Imports System.Collections.ObjectModel 
Imports System.Runtime.InteropServices 

Partial Public Class StoredProcedures 
    <Microsoft.SqlServer.Server.SqlProcedure()> _ 
    Public Shared Sub sp_ConvertTime(ByVal UTCTime As DateTime, ByVal ZoneID As String, <Out()> ByRef Output As DateTime) 
    Dim sp As SqlPipe = SqlContext.Pipe 

    Dim ConvertedTime As DateTime 
    Dim tzUTC = TimeZoneInfo.FindSystemTimeZoneById("UTC") 
    Dim tzNew = TimeZoneInfo.FindSystemTimeZoneById(ZoneID) 

    ConvertedTime = TimeZoneInfo.ConvertTime(UTCTime, tzUTC, tzNew) 

    Output = ConvertedTime 
    sp.Send(ConvertedTime) 

    ConvertedTime = Nothing 
    tzUTC = Nothing 
    tzNew = Nothing 
    sp = Nothing 

End Sub 
End Class 

Trước khi triển khai tôi thiết lập mức độ Permission để không an toàn.

Tiếp theo, tôi đã triển khai nó ra Tôi đã kiểm tra cửa sổ Đầu ra để xây dựng lỗi và sửa chữa chúng.

Đây là thử nghiệm SQL

DECLARE @UTCTime datetime 
DECLARE @ZoneID varchar(21) 
DECLARE @NewTime datetime 

SET @UTCTime = GETUTCDATE() 
SET @ZoneID = 'Central Standard Time' 

exec sp_ConvertTime @UTCTime, @ZoneID, @NewTime OUTPUT 
select @NewTime AS NewTime 
0

Sau khi chiến đấu với cùng một vấn đề trong nhiều năm, cuối cùng tôi quyết định xây dựng một giải pháp cho SQL Server Time Zone Support. Dự án sử dụng các múi giờ IANA tiêu chuẩn, as listed here.

Ví dụ:

SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'America/Los_Angeles') 

Tôi nhận ra đây không phải là chính xác chuyện gì đang hỏi, nhưng tôi nghĩ rằng nó sẽ giải quyết vấn đề tốt như nhau.

Các vấn đề liên quan