مثالهای عملی
مثال 1: کاربرد پایه با مقدار ثابت
در نخستین مثال، TODATETIMEOFFSET با ورودی صریح اجرا میشود تا شکل پایه خروجی روشن باشد.
SELECT TODATETIMEOFFSET(CAST('2026-07-19T12:00:00' AS datetime2), '+03:30') AS ResultValue;
| خروجی | نتیجه نمونه یا انتظار |
|---|
| نتیجه مثال 1 | یک مقدار قطعی متناسب با ورودی ثابت |
نکته کاربردی: این خروجی از نوع datetimeoffset با دقت ورودی است و پایه بررسی مثالهای بعدی محسوب میشود.
مثال 2: محاسبه روی چند ردیف داده نمونه
یک مجموعه تاریخ در CTE ساخته میشود و TODATETIMEOFFSET جداگانه روی هر ردیف عمل میکند.
WITH SampleDates(EventDate) AS
(
SELECT CAST('2026-01-15T08:20:00' AS datetime2)
UNION ALL
SELECT CAST('2026-07-19T14:45:30' AS datetime2)
UNION ALL
SELECT CAST('2026-12-31T23:59:59' AS datetime2)
)
SELECT EventDate, TODATETIMEOFFSET(d.EventDate, '+03:30') AS CalculatedValue
FROM SampleDates AS d;
| خروجی | نتیجه نمونه یا انتظار |
|---|
| نتیجه مثال 2 | سه ردیف همراه مقدار محاسبهشده |
نکته کاربردی: اجرای مجموعهمحور معمولاً از حلقه و پردازش ردیفبهردیف مناسبتر است.
مثال 3: استفاده در عبارت SELECT
در این سناریو خروجی TODATETIMEOFFSET با تابع دیگری ترکیب میشود تا شکل مناسب نمایش یا محاسبه ساخته شود.
SELECT SWITCHOFFSET(TODATETIMEOFFSET(CAST('2026-07-19T12:00:00' AS datetime2), '+03:30'), '+00:00') AS CombinedResult;
| خروجی | نتیجه نمونه یا انتظار |
|---|
| نتیجه مثال 3 | مقدار تبدیلشده یا ترکیبی |
نکته کاربردی: نوع تبدیل نهایی را صریح انتخاب کنید تا رفتار به تنظیمات نشست وابسته نشود.
مثال 4: استفاده در شرط WHERE
این Query نشان میدهد خروجی TODATETIMEOFFSET چگونه میتواند بخشی از شرط انتخاب داده باشد.
WITH SampleDates(EventDate) AS
(
SELECT CAST('2026-01-15T08:20:00' AS datetime2)
UNION ALL
SELECT CAST('2026-07-19T14:45:30' AS datetime2)
UNION ALL
SELECT CAST('2026-12-31T23:59:59' AS datetime2)
)
SELECT EventDate
FROM SampleDates AS d
WHERE TODATETIMEOFFSET(d.EventDate, '+03:30') IS NOT NULL;
| خروجی | نتیجه نمونه یا انتظار |
|---|
| نتیجه مثال 4 | ردیفهایی که نتیجه معتبر دارند |
نکته کاربردی: برای جدول بزرگ، اثر تابع روی SARGability و امکان استفاده از ایندکس را بررسی کنید.
مثال 5: ترکیب با توابع دیگر تاریخ
ترکیب TODATETIMEOFFSET با ابزارهای تاریخ SQL Server یک خروجی قابل استفاده در منطق کسبوکار میسازد.
SELECT SWITCHOFFSET(TODATETIMEOFFSET(CAST('2026-07-19T12:00:00' AS datetime2), '+03:30'), '+00:00') AS BusinessValue, TODATETIMEOFFSET(CAST('2026-07-19T12:00:00' AS datetime2), '+03:30') AS BaseValue;
| خروجی | نتیجه نمونه یا انتظار |
|---|
| نتیجه مثال 5 | دو ستون پایه و ترکیبی |
نکته کاربردی: نمایش همزمان ورودی و خروجی، تست و عیبیابی تبدیل را سادهتر میکند.
مثال 6: رفتار در برابر NULL
این مثال مشخص میکند وقتی یکی از ورودیهای TODATETIMEOFFSET تهی باشد چه خروجی دریافت میشود.
SELECT TODATETIMEOFFSET(CAST(NULL AS datetime2), '+03:30') AS NullResult;
| خروجی | نتیجه نمونه یا انتظار |
|---|
| نتیجه مثال 6 | NULL یا مقدار کنترلشده تابع |
نکته کاربردی: پیش از جایگزینی NULL با مقدار پیشفرض، معنای تجاری نبود داده را مشخص کنید.
مثال 7: بررسی حالت مرزی
یک مقدار مرزی معتبر برای آزمودن دقت، دامنه یا تغییر دوره در TODATETIMEOFFSET انتخاب شده است.
SELECT TODATETIMEOFFSET(CAST('2026-01-01T00:00:00' AS datetime2), '+14:00') AS BoundaryResult;
| خروجی | نتیجه نمونه یا انتظار |
|---|
| نتیجه مثال 7 | نتیجه معتبر در مرز تعریفشده |
نکته کاربردی: لحظه ورودی جابهجا نمیشود؛ فقط Offset به آن نسبت داده میشود.
مثال 8: سناریوی گزارشگیری سازمانی
در این مثال، TODATETIMEOFFSET برای تولید کلید گزارش یا دستهبندی سفارشها استفاده میشود.
DECLARE @Orders TABLE (OrderId int, EventDate datetime2, Amount decimal(10,2));
INSERT INTO @Orders VALUES
(1,'2026-01-15T08:20:00',120.00),
(2,'2026-01-20T10:00:00',180.00),
(3,'2026-07-19T14:45:30',250.00);
SELECT TODATETIMEOFFSET(d.EventDate, '+03:30') AS ReportKey, COUNT(*) AS OrderCount, SUM(d.Amount) AS TotalAmount
FROM @Orders AS d
GROUP BY TODATETIMEOFFSET(d.EventDate, '+03:30');
| خروجی | نتیجه نمونه یا انتظار |
|---|
| نتیجه مثال 8 | چند گروه گزارش با تعداد و مبلغ |
نکته کاربردی: در گزارش پرتکرار، ستون محاسبهشده پایدار یا جدول تقویم میتواند هزینه CPU را کاهش دهد.
مثال 9: روش اشتباه و نسخه اصلاحشده
ابتدا یک اشتباه رایج مرتبط با TODATETIMEOFFSET در TRY/CATCH مهار میشود و سپس روش روشنتر اجرا میگردد.
BEGIN TRY
EXEC sys.sp_executesql N'SELECT CAST(''2026-07-19T12:00:00'' AS datetimeoffset) AS ImplicitOffset;';
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
SELECT TODATETIMEOFFSET(CAST('2026-07-19T12:00:00' AS datetime2), '+03:30') AS ExplicitOffset;
| خروجی | نتیجه نمونه یا انتظار |
|---|
| نتیجه مثال 9 | پیام خطا یا تفاوت خروجی روشها |
نکته کاربردی: ورودیهای صریح، قالب ISO و نوع داده مشخص از خطاهای وابسته به نشست جلوگیری میکنند.
مثال 10: الگوی مناسب برای ایندکس
هدف این مثال حفظ امکان Seek است؛ بنابراین TODATETIMEOFFSET روی ستون EventDate در Predicate اصلی اجرا نمیشود.
DECLARE @Start date = DATEFROMPARTS(2026, 7, 1);
DECLARE @End date = DATEADD(month, 1, @Start);
DECLARE @Events TABLE (EventId int, EventDate datetime2, INDEX IX_EventDate NONCLUSTERED (EventDate));
INSERT INTO @Events VALUES (1,'2026-06-30'),(2,'2026-07-10'),(3,'2026-08-01');
-- از قرار دادن TODATETIMEOFFSET روی EventDate در شرط اصلی پرهیز میکنیم.
SELECT EventId, EventDate
FROM @Events
WHERE EventDate >= @Start AND EventDate < @End;
| خروجی | نتیجه نمونه یا انتظار |
|---|
| نتیجه مثال 10 | فقط EventId برابر 2 |
نکته کاربردی: Offset ورودی را اعتبارسنجی کنید و آن را با منطقه زمانی واقعی کاربر اشتباه نگیرید.
سؤالات متداول
تابع TODATETIMEOFFSET دقیقاً چه کاری انجام میدهد؟
یک datetime2 بدون Offset را با Offset مشخص برچسبگذاری و به datetimeoffset تبدیل میکند. مهم است که ورودیها با نوع داده صریح ارسال شوند و خروجی datetimeoffset با دقت ورودی در طراحی ستون مقصد لحاظ شود.
برای شروع کار با TODATETIMEOFFSET چه چیزی باید بدانیم؟
ابتدا نحو TODATETIMEOFFSET(datetime2_expression, timezoneoffset_expression) را یاد بگیرید، سپس با مقدار ISO ثابت آزمایش کنید. بعد از اطمینان از نوع خروجی، آن را وارد Query واقعی کنید.
TODATETIMEOFFSET در پروژههای تجاری چه کاربردی دارد؟
این تابع در گزارشگیری، کنترل مهلت، ثبت رخداد و پاکسازی دادههای زمانی کاربرد دارد. در پروژه سازمانی باید منطقه زمانی، دقت و حجم داده نیز در طراحی بررسی شود.
آیا استفاده از TODATETIMEOFFSET هزینه توسعه را کاهش میدهد؟
استفاده درست از قابلیت داخلی SQL Server معمولاً کد برنامه را ساده و رفتار را یکپارچه میکند. برای Queryهای حساس، بازبینی تخصصی طرح اجرا و ایندکس همچنان ارزشمند است.
تفاوت TODATETIMEOFFSET با روشهای تبدیل دستی چیست؟
تابع داخلی قواعد نوع داده و خطا را شفافتر اعمال میکند، در حالی که اتصال رشته یا تبدیل دستی ممکن است به LANGUAGE و DATEFORMAT وابسته شود. انتخاب نهایی به دقت و نسخه SQL Server بستگی دارد.
برای پیادهسازی حرفهای TODATETIMEOFFSET میتوان از خدمات مشاوره استفاده کرد؟
بله؛ در مهاجرت داده، طراحی گزارش و بهینهسازی Query، بررسی نمونه داده و Execution Plan توسط متخصص SQL Server میتواند از خطاهای زمانی پرهزینه جلوگیری کند.
خطای رایج هنگام استفاده از TODATETIMEOFFSET چیست؟
ورودی مبهم، نوع مقصد نامتناسب یا عبور از دامنه معتبر از خطاهای رایج است. استفاده از قالب ISO، CAST صریح و تست حالت مرزی راه پیشگیری است.
اثر TODATETIMEOFFSET بر Performance چیست؟
محاسبه تابع برای هر ردیف CPU مصرف میکند و اگر روی ستون ایندکسشده در WHERE قرار گیرد ممکن است Seek را دشوار کند. Offset ورودی را اعتبارسنجی کنید و آن را با منطقه زمانی واقعی کاربر اشتباه نگیرید.
Best Practice اصلی برای TODATETIMEOFFSET چیست؟
نوع داده مناسب، قرارداد ثابت UTC یا زمان محلی، ورودی صریح و تست NULL را مستند کنید. خروجی را قبل از انتشار با داده واقعی و مرزهای تقویمی کنترل کنید.
TODATETIMEOFFSET با کدام نسخههای SQL Server سازگار است؟
وضعیت سازگاری این تابع: SQL Server 2008 و جدیدتر. علاوه بر نسخه موتور، Compatibility Level پایگاه داده و نوع مقصد را نیز بررسی کنید.