آموزش تابع TRY_PARSE در SQL Server برای داده چندفرهنگی
مقدمه
تابع TRY_PARSE یکی از ابزارهای مهم تبدیل داده در Microsoft SQL Server است. تبدیل نوع فقط تغییر ظاهر مقدار نیست؛ نوع مقصد بر مقایسه، دقت محاسبه، مرتبسازی، مصرف حافظه و امکان استفاده از ایندکس اثر میگذارد. در این راهنما از مثال ساده آغاز میکنیم و سپس سناریوهای پاکسازی داده، گزارشگیری، مدیریت NULL و بهینهسازی را بررسی میکنیم.
اگر نوع ستون با معنای واقعی داده هماهنگ باشد، نیاز به تبدیل در Queryها کمتر و طراحی پایدارتر میشود. با این حال در مرزهای سامانه مانند فایل ورودی، API، گزارش متنی و اتصال به نرمافزار قدیمی، استفاده آگاهانه از TRY_PARSE ضروری است. هر مثال این مقاله کامل، مستقل و دارای خروجی مورد انتظار است تا بتوانید رفتار را در محیط آزمایشی بررسی کنید.
برای دیدن جایگاه این تابع در کنار پنج گزینه دیگر، راهنمای جامع توابع تبدیل داده در SQL Server را نیز مطالعه کنید. آن مقاله یک جدول تصمیم دارد و نشان میدهد چه زمانی تبدیل استاندارد، نسخه امن، Style یا Culture انتخاب مناسبتری است.
تعریف تابع TRY_PARSE
TRY_PARSE نسخه امنتر PARSE برای رشتههای عددی و تاریخی وابسته به Culture است. اگر متن مطابق قواعد فرهنگ انتخابشده نباشد، معمولاً NULL برمیگرداند و پردازش سایر ردیفها ادامه مییابد. این تابع همچنان از CLR استفاده میکند؛ بنابراین برای تبدیلهای ساده یا حجم بسیار زیاد، نخست گزینههای بومی SQL Server را بررسی کنید.
وجود واژه TRY به این معنی است که بسیاری از شکستهای قالبی به NULL تبدیل میشوند، اما مسئولیت ثبت و تحلیل شکست از بین نمیرود. از آنجا که تفسیر به Culture وابسته است، متادیتای زبان و منطقه بخشی از خود داده محسوب میشود.
نحو یا Syntax
-- Syntax
TRY_PARSE ( string_value AS data_type [ USING culture ] )
پارامترها
- string_value: رشته ورودی که باید بر اساس قواعد فرهنگی تفسیر شود.
- data_type: یکی از نوعهای عددی یا تاریخوزمان پشتیبانیشده.
- culture: نام Culture اختیاری .NET؛ در نبود آن زبان Session مبنا قرار میگیرد.
نوع خروجی و رفتار خطا
در تبدیل موفق، مقدار مقصد و در شکست معمولی NULL برمیگردد. Culture نامعتبر میتواند خطا بدهد و TRY_PARSE راهکاری برای تبدیل میان هر دو نوع دلخواه SQL Server نیست.
| معیار | راهنمای استفاده |
|---|
| نوع مبدأ | نوع واقعی عبارت و اولویت انواع SQL Server را بررسی کنید. |
| نوع مقصد | طول، precision، scale و دقت زمانی را صریح انتخاب کنید. |
| داده نامعتبر | خروجی NULL را ثبت و از NULL اصلی تفکیک کنید. |
| حجم بالا | هزینه CLR را اندازه بگیرید و تبدیل را یکبار در Staging انجام دهید. |
چه زمانی از TRY_PARSE استفاده کنیم؟
این تابع زمانی ارزش دارد که یک رشته واقعاً بر اساس قواعد منطقهای مانند جداکننده اعشار، نماد پول یا نام ماه معنا پیدا کند. اگر داده در اختیار شماست، اصلاح نوع ستون در طراحی پایگاه داده معمولاً بهتر از تکرار تبدیل در همه Queryها خواهد بود.
تبدیل را نزدیک مرزی انجام دهید که داده از متن یا سامانه خارجی وارد مدل استاندارد میشود. مقدار خام را برای حسابرسی حفظ کنید، مقدار تبدیلشده را در نوع درست بنویسید و وضعیت اعتبارسنجی را جدا نگه دارید. این الگو سبب میشود گزارشها سادهتر، ایندکسها مؤثرتر و مسئولیت کیفیت داده شفافتر باشد.
در عملیات مالی، precision و scale را از قبل محاسبه کنید. در متن فارسی nvarchar و پیشوند N را بهکار ببرید. برای تاریخوزمان نیز میان date، datetime2 و datetimeoffset تفاوت بگذارید؛ تبدیل یک زمان محلی به متن، آن را خودکار به UTC تبدیل نمیکند و Offset باید در قرارداد سامانه مشخص باشد.
مثالهای عملی
مثال 1: تبدیل امن تاریخ آمریکایی
TRY_PARSE یک تاریخ معتبر آمریکایی را با Culture صریح به date تبدیل میکند. این حالت نتیجهای مشابه PARSE دارد، اما برای ورودی خراب معمولاً NULL خواهد داد.
SELECT TRY_PARSE('7/19/2026' AS date USING 'en-US') AS ParsedDate;
نکته کاربردی: برای یک قالب کاملاً مشخص و غیرفرهنگی مانند ISO، TRY_CONVERT انتخاب سادهتر و سریعتری است.
مثال 2: رد آرام تاریخ نامعتبر
این رشته روزی ناممکن در ماه فوریه دارد. TRY_PARSE بهجای متوقف کردن دسته، NULL برمیگرداند تا ردیف در مسیر Reject قرار گیرد.
SELECT TRY_PARSE('2/30/2026' AS date USING 'en-US') AS ParsedDate;
نکته کاربردی: NULL خروجی را همراه متن خام و علت احتمالی در جدول خطا ذخیره کنید تا قابلیت پیگیری حفظ شود.
مثال 3: تبدیل امن عدد آلمانی
جداکنندههای متن بر اساس de-DE تفسیر میشوند و مقدار به decimal استاندارد تبدیل میشود. اگر متن با Culture هماهنگ نباشد خروجی امن NULL است.
SELECT TRY_PARSE('9.876,54' AS decimal(12,2) USING 'de-DE') AS Amount;
نکته کاربردی: پس از تبدیل، دیگر قالب فرهنگی در عدد ذخیره نمیشود؛ Culture باید بهعنوان متادیتای ورودی یا ترجیح نمایش نگهداری شود.
مثال 4: تشخیص Culture اشتباه برای یک مبلغ
یک متن آمریکایی با Culture آلمانی ممکن است معنایی متفاوت یا شکست تبدیل داشته باشد. این مثال وضعیت را با Culture صحیح en-US کنترل میکند.
DECLARE @Text nvarchar(30) = N'$1,250.75';
SELECT TRY_PARSE(@Text AS money USING 'en-US') AS CorrectAmount;
نکته کاربردی: موفق شدن تبدیل همیشه اثبات معنای درست نیست؛ جداکننده مبهم ممکن است عددی معتبر اما اشتباه بسازد، پس Culture منبع حیاتی است.
مثال 5: جداسازی ردیفهای معتبر چندفرهنگی
جدول ورودی هم متن و هم Culture هر ردیف را دارد. CROSS APPLY نتیجه تبدیل را یکبار محاسبه و فقط قیمتهای قابل قبول را برمیگرداند.
DECLARE @Feed TABLE (Id int, ValueText nvarchar(30), CultureName nvarchar(10));
INSERT INTO @Feed VALUES
(1,N'1,200.50',N'en-US'),(2,N'خطا',N'fa-IR'),(3,N'1.200,50',N'de-DE');
SELECT f.Id, x.Amount
FROM @Feed AS f
CROSS APPLY (VALUES(TRY_PARSE(f.ValueText AS decimal(12,2) USING f.CultureName))) AS x(Amount)
WHERE x.Amount IS NOT NULL;
نکته کاربردی: نام Culture را از فهرست مورد اعتماد بگیرید؛ Culture ناشناخته میتواند برخلاف شکست متن، خطا ایجاد کند.
مثال 6: تمایز NULL ورودی از متن خراب
CASE ابتدا نبود مقدار را بررسی میکند و سپس نتیجه TRY_PARSE را میسنجد. این ترتیب مانع آن میشود که فیلد اختیاری خالی بهعنوان خطای کیفیت ثبت شود.
DECLARE @Input nvarchar(30) = N'unknown';
SELECT CASE WHEN @Input IS NULL THEN N'خالی'
WHEN TRY_PARSE(@Input AS date USING 'en-US') IS NULL THEN N'نامعتبر'
ELSE N'معتبر' END AS Status;
نکته کاربردی: قواعد اجباری یا اختیاری بودن فیلد را بیرون تابع تبدیل تعریف کنید؛ TRY_PARSE فقط قابلیت تفسیر متن را میسنجد.
مثال 7: کنترل عدد خارج از ظرفیت مقصد
متن میتواند از نظر Culture درست اما برای decimal انتخابشده بیش از حد بزرگ باشد. TRY_PARSE شکست ظرفیت را به NULL تبدیل میکند و از سرریز دستهای جلوگیری میشود.
SELECT TRY_PARSE('9999999999.99' AS decimal(8,2) USING 'en-US') AS SmallDecimal;
نکته کاربردی: precision مقصد باید دامنه کسبوکار را پوشش دهد؛ نرخ بالای این خطا نشانه نیاز به بازطراحی نوع یا کنترل سقف ورودی است.
مثال 8: محاسبه نرخ خطای فایل بینالمللی
گزارش کیفیت تعداد مقدارهای ارائهشده و تبدیلهای موفق را برای یک Culture مشخص مقایسه میکند. اختلاف این دو تعداد همان شکستهای قابل پیگیری است.
DECLARE @Feed TABLE (ValueText nvarchar(30));
INSERT INTO @Feed VALUES (N'10.50'),(N'bad'),(N'20.25'),(NULL);
SELECT COUNT(ValueText) AS Provided,
COUNT(TRY_PARSE(ValueText AS decimal(10,2) USING 'en-US')) AS Valid,
COUNT(ValueText)-COUNT(TRY_PARSE(ValueText AS decimal(10,2) USING 'en-US')) AS Invalid
FROM @Feed;
نکته کاربردی: شاخص را برای هر شریک و Culture جدا کنید تا منبع اصلی خطا پنهان نشود و SLA داده قابل اندازهگیری باشد.
مثال 9: Fallback کنترلشده میان دو Culture
گاهی سامانه موقتاً دو قرارداد شناختهشده را میپذیرد. COALESCE ابتدا Culture اصلی و سپس Culture جایگزین را امتحان میکند؛ ترتیب باید مستند و محدود باشد.
DECLARE @Text nvarchar(30) = N'19.07.2026';
SELECT COALESCE(
TRY_PARSE(@Text AS date USING 'en-US'),
TRY_PARSE(@Text AS date USING 'de-DE')
) AS ParsedDate;
نکته کاربردی: Fallback گسترده میتواند مقدار مبهم را با معنای اشتباه بپذیرد؛ فقط Cultureهای قطعی و دارای اولویت کسبوکاری را آزمایش کنید.
مثال 10: انتقال تبدیل از گزارش به مرحله ورود
اجرای TRY_PARSE در هر گزارش هزینه CLR را تکرار میکند. الگوی پایدار مقدار خام، Culture، مقدار استاندارد و وضعیت تبدیل را در Staging ذخیره و گزارش را روی ستون عددی اجرا میکند.
SELECT ProductId, NormalizedPrice
FROM dbo.ImportedPrices
WHERE ParseStatus = N'Valid'
AND NormalizedPrice >= 1000.00;
-- ایندکس پیشنهادی روی ستون استاندارد
CREATE INDEX IX_ImportedPrices_NormalizedPrice
ON dbo.ImportedPrices(NormalizedPrice)
WHERE ParseStatus = N'Valid';
| طراحی | مزیت |
|---|
| تبدیل یکباره هنگام ورود | کاهش هزینه CLR و جستوجوی ایندکسی |
نکته کاربردی: TRY_PARSE ابزار محافظ مرز ورودی است، نه جایگزین نوع داده درست. متن را برای حسابرسی نگه دارید و مصرف تحلیلی را بر ستون استاندارد بنا کنید.
NULL، داده مرزی و اعتبارسنجی
NULL نشانه ناشناخته یا نبود مقدار است و نباید بدون تصمیم کسبوکاری با صفر یا رشته خالی جایگزین شود. در کار با TRY_PARSE ابتدا NULL اصلی را بررسی کنید، سپس شکست تبدیل را بسنجید و در نهایت قواعد دامنه مانند حداقل، حداکثر و تعداد رقم را اعمال کنید. تبدیل شدن یک متن به عدد یا تاریخ فقط اعتبار نحوی و نوعی را نشان میدهد، نه الزاماً معتبر بودن آن برای فرآیند سازمانی.
دادههای مرزی شامل بزرگترین عدد مجاز، متن با طول دقیق مقصد، زمانهای نزدیک تغییر روز، تاریخ ناممکن، نویسههای یونیکد و رشته دارای فاصله هستند. برای هرکدام تست خودکار بنویسید و نتیجه را در نسخه هدف SQL Server کنترل کنید. همچنین Collation، زبان Session و DATEFORMAT را در تست یکپارچگی نادیده نگیرید.
خطاهای رایج
- اعتماد به تبدیل ضمنی و نادیده گرفتن اولویت نوعهای داده در عبارت یا Join.
- ننوشتن طول varchar یا nvarchar و بریده شدن خروجی در یکی از مسیرهای اجرا.
- انتخاب decimal با precision ناکافی و ایجاد سرریز یا گرد شدن ناخواسته.
- حدس زدن Culture از ظاهر رشته و پذیرش عدد یا تاریخ معتبر اما با معنای اشتباه.
- قرار دادن تابع تبدیل روی ستون ایندکسشده در WHERE و دشوار کردن Index Seek.
- نادیده گرفتن خروجی NULL نسخههای TRY و گزارش کردن جمع ناقص بهعنوان نتیجه کامل.
رفع خطا فقط با پیچیدن عبارت در یک تابع TRY کامل نمیشود. باید مالک داده خراب، مسیر اصلاح، حد قابل قبول نرخ شکست و رفتار تراکنش مشخص باشد. سامانه مقاوم خطا را مدیریت میکند، اما آن را پنهان نمیکند.
نکات Performance و بهینهسازی
هزینه یک تبدیل منفرد معمولاً کم است، ولی ضرب آن در میلیونها ردیف محسوس میشود. خانواده PARSE از CLR استفاده میکند و باید فقط برای معنای فرهنگی واقعی انتخاب شود. Actual Execution Plan، زمان CPU، تعداد خواندن منطقی و تخمین Cardinality را پیش و پس از تغییر مقایسه کنید.
اگر Predicate روی CAST یا CONVERT ستون نوشته شود، موتور ممکن است نتواند از ترتیب ایندکس بهطور مستقیم استفاده کند. بهجای آن پارامتر را به نوع ستون تبدیل کنید، برای تاریخ از بازه نیمهباز استفاده کنید یا مقدار استاندارد را در ستون مناسب ذخیره کنید. ستون محاسباتی Persisted و ایندکس فیلترشده گاهی مفیدند، اما باید قطعی بودن عبارت و هزینه نگهداری آنها ارزیابی شود.
در فرآیند ETL، تبدیل و اعتبارسنجی را یکبار در Staging انجام دهید. سپس ردیف سالم را به جدول نهایی و ردیف خراب را با علت و متن خام به Reject بفرستید. این طراحی هم گزارش را سریع میکند و هم امکان حسابرسی و اصلاح دستهای را فراهم میآورد.
بهترین روشها
- نوع مقصد را از مدل کسبوکار انتخاب کنید، نه از یک نمونه محدود داده.
- طول متن و precision و scale عدد را همیشه صریح بنویسید.
- قالب تاریخ ورودی را ISO یا Style مشخص و مستند نگه دارید.
- NULL اصلی، شکست تبدیل و نقض دامنه را سه وضعیت جدا در نظر بگیرید.
- تبدیل را روی پارامتر یا هنگام ورود انجام دهید و ستون ایندکسشده را در شرط دستنخورده نگه دارید.
- برای متن فارسی از nvarchar و رشتههای N استفاده کنید.
- نتیجه و Plan را با داده واقعی و نسخه هدف SQL Server آزمایش کنید.
کاربردهای واقعی
TRY_PARSE میتواند در ورود فایل فروش، پاکسازی داده CRM، تبدیل تاریخ قرارداد، ساخت خروجی API، مهاجرت سامانه قدیمی، کنترل فرم کاربر و آمادهسازی Data Warehouse استفاده شود. نقطه مشترک همه سناریوها وجود یک قرارداد روشن میان متن خام و نوع استاندارد است.
در پروژه سازمانی بهتر است منطق تبدیل در View یا گزارشهای متعدد کپی نشود. Procedure ورودی، Pipeline ETL یا لایه سرویس مشترک میتواند قرارداد را متمرکز کند. این تمرکز تست، پایش نرخ خطا، تغییر نسخه و ارائه خدمات پشتیبانی پایگاه داده را بسیار سادهتر میسازد.
سؤالات متداول
پرسش متداول 1: TRY_PARSE در SQL Server دقیقاً چه کاری انجام میدهد؟
TRY_PARSE مقدار ورودی را به نوع مقصد تبدیل میکند و ویژگی شاخص آن قواعد Culture در .NET است. انتخاب نوع مقصد، طول، precision و scale بخشی از قرارداد داده محسوب میشود و نباید به پیشفرضها واگذار شود.
پرسش متداول 2: خروجی و رفتار خطای TRY_PARSE چگونه است؟
خروجی از نوع مقصد اعلامشده خواهد بود. در شکستهای معمول تبدیل NULL میدهد، هرچند تبدیلهای صریحاً ممنوع همچنان ممکن است خطا ایجاد کنند. برای طراحی درست باید NULL واقعی ورودی، شکست تبدیل و مقدار خارج از دامنه را جداگانه پایش کنید.
پرسش متداول 3: آیا یادگیری TRY_PARSE برای پروژههای تجاری SQL Server ضروری است؟
بله؛ بسیاری از خطاهای مالی، تاریخی و یکپارچهسازی از تبدیل ضمنی یا نوع مقصد نامناسب ناشی میشوند. آموزش عملی این تابع هزینه رفع خطا و دوبارهکاری گزارشها را کاهش میدهد.
پرسش متداول 4: استفاده حرفهای از TRY_PARSE چه ارزش تجاری ایجاد میکند؟
قرارداد تبدیل روشن، داده قابل اعتمادتر، گزارش دقیقتر و فرآیند ورود مقاومتر میسازد. در پروژههای سازمانی میتوان با بازبینی Queryها و مشاوره SQL Server نقاط تبدیل پرریسک را پیش از اختلال شناسایی کرد.
پرسش متداول 5: TRY_PARSE را در مقایسه با سایر توابع تبدیل چه زمانی انتخاب کنیم؟
وقتی معنای رشته به Culture واقعی وابسته است این تابع مناسب است؛ برای قالب ثابت معمولاً TRY_CONVERT یا CONVERT سبکتر است.
پرسش متداول 6: برای پیادهسازی TRY_PARSE در Procedure موجود چه خدمتی لازم است؟
ابتدا نمونه داده، نوع ستونها، تنظیم زبان Session، حجم ردیف و Plan اجرایی بررسی میشود. سپس میتوان نسخه آزمایشی، تست مرزی و راهکار مهاجرت را در قالب مشاوره یا انجام پروژه SQL Server آماده کرد.
پرسش متداول 7: رایجترین خطا هنگام کار با TRY_PARSE چیست؟
انتخاب Culture اشتباه یا حدس زدن Culture از ظاهر متن، خطای اصلی است. متن خام و قرارداد منبع را در تستها نگه دارید.
پرسش متداول 8: TRY_PARSE چه اثری بر Performance دارد؟
این تابع به CLR متکی است و روی حجم بالا معمولاً از تبدیلهای بومی هزینه بیشتری دارد. تبدیل را ترجیحاً در مرز ورود یا روی پارامتر انجام دهید.
پرسش متداول 9: بهترین روش استفاده از TRY_PARSE چیست؟
نوع مقصد و طول را صریح تعیین کنید، حالتهای NULL و سرریز را تست کنید، شکستها را ثبت کنید و مقدار استاندارد را برای مصرفهای بعدی نگه دارید. قالببندی نمایشی را تا حد امکان به لایه نمایش بسپارید.
پرسش متداول 10: TRY_PARSE در کدام نسخههای SQL Server قابل استفاده است؟
این تابع از SQL Server 2012 در دسترس است و در نسخههای جدید SQL Server و Azure SQL نیز پشتیبانی میشود؛ سطح سازگاری و محدودیت Remoting را بررسی کنید.
سؤالات مصاحبه SQL Server
سؤال مصاحبه 1: تفاوت تبدیل ضمنی و TRY_PARSE چیست؟
در تبدیل ضمنی موتور بر اساس اولویت انواع تصمیم میگیرد، اما تابع تبدیل قصد و نوع مقصد را صریح میکند. تبدیل ضمنی روی سمت نامناسب Join یا Predicate میتواند هم خطا و هم افت کارایی ایجاد کند.
سؤال مصاحبه 2: TRY_PARSE با TRY_CONVERT چه تفاوتی دارد؟
نسخه TRY در شکستهای معمول NULL میدهد، در حالی که نسخه قطعی خطا ایجاد میکند؛ هر دو تابع از نظر محدوده تبدیل و نوع مقصد قواعد SQL Server را رعایت میکنند.
سؤال مصاحبه 3: چرا تبدیل ستون در WHERE ممکن است بد باشد؟
چون عبارت روی ستون میتواند جستوجو را غیر SARGable کند و مانع استفاده مستقیم از کلید مرتب ایندکس شود. معمولاً تبدیل پارامتر یا شرط بازهای Plan بهتری میسازد.
سؤال مصاحبه 4: چگونه شکستهای تبدیل را بدون پنهان کردن خطا مدیریت میکنید؟
متن خام، مقدار استاندارد، وضعیت و علت Reject را جدا ذخیره میکنم؛ نرخ شکست را مانیتور و برای عبور از آستانه هشدار تعریف میکنم. NULL حاصل نباید بیگزارش از محاسبات حذف شود.
سؤال مصاحبه 5: برای تست تبدیل چه حالتهایی لازم است؟
مقدار سالم، NULL، رشته خالی، نویسه یونیکد، حداقل و حداکثر نوع، سرریز، طول بیش از مقصد، تاریخ ناممکن، Culture متفاوت و حجم واقعی باید پوشش داده شوند.
چکلیست نهایی
- نوع مقصد TRY_PARSE با دامنه واقعی داده هماهنگ است.
- طول متن، precision، scale یا دقت زمانی صریح تعیین شده است.
- رفتار NULL، ورودی خراب و سرریز با تست پوشش داده شده است.
- هیچ تابع غیرضروری روی ستون ایندکسشده در Predicate اجرا نمیشود.
- خروجی تبدیل ناموفق ثبت، شمارش و برای اصلاح قابل ردیابی است.
- Query روی نسخه هدف SQL Server و با حجم نزدیک تولید آزمایش شده است.
جمعبندی
TRY_PARSE زمانی ارزشمند است که با شناخت نوع داده، کیفیت منبع و مسیر مصرف انتخاب شود. مثالهای این مقاله نشان دادند چگونه تبدیل ساده، NULL، داده مرزی، گزارش سازمانی و کارایی را در یک طراحی قابل اعتماد کنار هم قرار دهیم. اصل مهم این است که تبدیل را بخشی از قرارداد داده بدانیم، نه وصلهای برای پوشاندن نوع ستون نامناسب.
برای مقایسه دوباره گزینهها و دسترسی به مقالههای مرتبط، به راهنمای جامع CAST، CONVERT، TRY_CAST، TRY_CONVERT، PARSE و TRY_PARSE بازگردید.