آموزش تابع PARSE در SQL Server و Cultureهای مختلف
مقدمه
تابع PARSE یکی از ابزارهای مهم تبدیل داده در Microsoft SQL Server است. تبدیل نوع فقط تغییر ظاهر مقدار نیست؛ نوع مقصد بر مقایسه، دقت محاسبه، مرتبسازی، مصرف حافظه و امکان استفاده از ایندکس اثر میگذارد. در این راهنما از مثال ساده آغاز میکنیم و سپس سناریوهای پاکسازی داده، گزارشگیری، مدیریت NULL و بهینهسازی را بررسی میکنیم.
اگر نوع ستون با معنای واقعی داده هماهنگ باشد، نیاز به تبدیل در Queryها کمتر و طراحی پایدارتر میشود. با این حال در مرزهای سامانه مانند فایل ورودی، API، گزارش متنی و اتصال به نرمافزار قدیمی، استفاده آگاهانه از PARSE ضروری است. هر مثال این مقاله کامل، مستقل و دارای خروجی مورد انتظار است تا بتوانید رفتار را در محیط آزمایشی بررسی کنید.
برای دیدن جایگاه این تابع در کنار پنج گزینه دیگر، راهنمای جامع توابع تبدیل داده در SQL Server را نیز مطالعه کنید. آن مقاله یک جدول تصمیم دارد و نشان میدهد چه زمانی تبدیل استاندارد، نسخه امن، Style یا Culture انتخاب مناسبتری است.
تعریف تابع PARSE
PARSE یک رشته را با استفاده از زیرساخت .NET و قواعد فرهنگ زبانی مشخص به عدد یا تاریخ و زمان تبدیل میکند. وقتی جداکننده اعشار، نماد پول یا ترتیب روز و ماه به Culture وابسته است، PARSE از CAST و CONVERT گویاتر است. این تابع فقط مقصدهای عددی و تاریخوزمان را پشتیبانی میکند و هزینه بیشتری دارد.
این تابع در ورودی ناسازگار معمولاً خطا ایجاد میکند؛ بنابراین برای داده خام باید مرحله اعتبارسنجی یا مدیریت خطا طراحی شود. از آنجا که تفسیر به Culture وابسته است، متادیتای زبان و منطقه بخشی از خود داده محسوب میشود.
نحو یا Syntax
-- Syntax
PARSE ( string_value AS data_type [ USING culture ] )
پارامترها
- string_value: عبارت متنی از نوع nvarchar؛ مقدارهای دیگر ابتدا به nvarchar(4000) تبدیل میشوند.
- data_type: نوع عددی یا نوع تاریخوزمان پشتیبانیشده.
- culture: نام Culture معتبر .NET مانند en-US، de-DE یا fa-IR.
نوع خروجی و رفتار خطا
خروجی از نوع عددی یا تاریخوزمان مقصد است. رشته نامعتبر یا Culture ناشناخته خطا ایجاد میکند. PARSE به CLR وابسته است و امکان Remoting آن وجود ندارد.
| معیار | راهنمای استفاده |
|---|
| نوع مبدأ | نوع واقعی عبارت و اولویت انواع SQL Server را بررسی کنید. |
| نوع مقصد | طول، precision، scale و دقت زمانی را صریح انتخاب کنید. |
| داده نامعتبر | پیش از تبدیل کیفیت را تضمین یا خطا را در مرز مناسب مدیریت کنید. |
| حجم بالا | هزینه CLR را اندازه بگیرید و تبدیل را یکبار در Staging انجام دهید. |
چه زمانی از PARSE استفاده کنیم؟
این تابع زمانی ارزش دارد که یک رشته واقعاً بر اساس قواعد منطقهای مانند جداکننده اعشار، نماد پول یا نام ماه معنا پیدا کند. اگر داده در اختیار شماست، اصلاح نوع ستون در طراحی پایگاه داده معمولاً بهتر از تکرار تبدیل در همه Queryها خواهد بود.
تبدیل را نزدیک مرزی انجام دهید که داده از متن یا سامانه خارجی وارد مدل استاندارد میشود. مقدار خام را برای حسابرسی حفظ کنید، مقدار تبدیلشده را در نوع درست بنویسید و وضعیت اعتبارسنجی را جدا نگه دارید. این الگو سبب میشود گزارشها سادهتر، ایندکسها مؤثرتر و مسئولیت کیفیت داده شفافتر باشد.
در عملیات مالی، precision و scale را از قبل محاسبه کنید. در متن فارسی nvarchar و پیشوند N را بهکار ببرید. برای تاریخوزمان نیز میان date، datetime2 و datetimeoffset تفاوت بگذارید؛ تبدیل یک زمان محلی به متن، آن را خودکار به UTC تبدیل نمیکند و Offset باید در قرارداد سامانه مشخص باشد.
مثالهای عملی
مثال 1: تبدیل تاریخ آمریکایی با Culture
در Culture آمریکایی ترتیب رایج ماه/روز/سال است. PARSE با ذکر en-US این قرارداد را مستقل از زبان Session اعمال و رشته را به date تبدیل میکند.
SELECT PARSE('7/19/2026' AS date USING 'en-US') AS ParsedDate;
نکته کاربردی: Culture را حدس نزنید؛ آن را از مشخصات منبع، تنظیم حساب کاربر یا متادیتای فایل دریافت کنید.
مثال 2: تبدیل تاریخ آلمانی
رشته آلمانی روز را پیش از ماه میآورد و با نقطه جدا میکند. Culture برابر de-DE قواعد لازم را برای تفسیر صحیح این متن فراهم میسازد.
SELECT PARSE('19.07.2026' AS date USING 'de-DE') AS ParsedDate;
نکته کاربردی: اگر ورودی از قبل ISO است، CONVERT یا CAST بومی سبکتر است و نیازی به فعالکردن مسیر CLR ندارد.
مثال 3: خواندن عدد اعشاری آلمانی
در بسیاری از Cultureهای اروپایی ویرگول جداکننده اعشار و نقطه جداکننده هزارگان است. PARSE مقدار متنی را بر اساس de-DE به decimal واقعی تبدیل میکند.
SELECT PARSE('1.234,56' AS decimal(12,2) USING 'de-DE') AS Amount;
نکته کاربردی: ذخیرهسازی نهایی باید عددی و مستقل از Culture باشد؛ Culture فقط در مرز خواندن یا نمایش متن نقش داشته باشد.
مثال 4: خواندن مبلغ آمریکایی دارای نماد پول
PARSE میتواند قواعد NumberStyles مربوط به نوع مقصد را به کمک .NET اعمال کند. نماد دلار و جداکننده هزارگان آمریکایی به money تبدیل میشوند.
SELECT PARSE('$1,250.75' AS money USING 'en-US') AS Amount;
نکته کاربردی: برای محاسبات مالی جدید decimal را بر money ترجیح دهید و نماد پول را جدا از مقدار و کد ارز نگه دارید.
مثال 5: پردازش جدول قیمت چندفرهنگی
هر ردیف Culture خودش را دارد و CROSS APPLY تبدیل مناسب را انجام میدهد. این الگو در Marketplaceهای بینالمللی کاربرد دارد، هرچند باید Cultureهای مجاز محدود و کنترل شوند.
DECLARE @Prices TABLE (Id int, PriceText nvarchar(30), CultureName nvarchar(10));
INSERT INTO @Prices VALUES
(1,N'1,234.50',N'en-US'),(2,N'1.234,50',N'de-DE');
SELECT Id, PARSE(PriceText AS decimal(12,2) USING CultureName) AS Price
FROM @Prices;
نکته کاربردی: این Query روی حجم کم مناسب است؛ برای حجم بالا، داده را در سرویس ورودی نرمال و فقط عدد استاندارد را وارد SQL Server کنید.
مثال 6: ترکیب PARSE با محاسبه مالی
پس از تبدیل متن فرهنگی به decimal، مقدار خروجی در محاسبه مالی شرکت میکند. ROUND قیمت شامل مالیات را به دو رقم اعشار محدود میکند.
DECLARE @PriceText nvarchar(30) = N'99,95';
SELECT ROUND(PARSE(@PriceText AS decimal(10,2) USING 'de-DE') * 1.20, 2) AS GrossPrice;
نکته کاربردی: نوع و قواعد گرد کردن را در سیاست مالی سامانه تعریف کنید؛ تبدیل صحیح متن تنها بخشی از صحت محاسبه است.
مثال 7: رفتار PARSE با NULL
اگر ورودی NULL باشد، PARSE نیز NULL برمیگرداند و خطا تولید نمیکند. این رفتار با رشته نامعتبر متفاوت است؛ رشته خراب در PARSE قطعی باعث خطا میشود.
DECLARE @Input nvarchar(30) = NULL;
SELECT PARSE(@Input AS decimal(10,2) USING 'en-US') AS Amount;
نکته کاربردی: NULL، رشته خالی و متن نامعتبر سه وضعیت جدا هستند؛ آنها را در Validation ورودی به یک معنا تقلیل ندهید.
مثال 8: نمونه خطای Culture و نسخه اصلاحشده
نوشتن Culture نادرست یا ناسازگار میتواند تبدیل را متوقف کند. نمونه خطادار در توضیح نگه داشته شده و Query قابل اجرا از نام استاندارد Culture استفاده میکند.
-- نام 'English-USA' معتبر نیست.
-- نسخه صحیح:
SELECT PARSE('July 19, 2026' AS date USING 'en-US') AS ParsedDate;
نکته کاربردی: فهرست Cultureهای پذیرفتهشده را در تنظیمات برنامه محدود کنید و مقدار آزاد کاربر را مستقیماً وارد USING نکنید.
مثال 9: گزارش سازمانی تاریخ سفارش خارجی
فایل شریک تجاری بریتانیایی تاریخها را با نام ماه ارسال میکند. PARSE قرارداد en-GB را اعمال و امکان گروهبندی بر مقدار date واقعی را فراهم میکند.
DECLARE @Orders TABLE (OrderId int, OrderedText nvarchar(40));
INSERT INTO @Orders VALUES (1,N'19 July 2026'),(2,N'20 July 2026');
SELECT OrderId, PARSE(OrderedText AS date USING 'en-GB') AS OrderedDate
FROM @Orders;
| OrderId | OrderedDate |
|---|
| 1 | 2026-07-19 |
| 2 | 2026-07-20 |
نکته کاربردی: پس از نخستین تبدیل موفق، مقدار استاندارد را ذخیره کنید تا هر گزارش مجبور به اجرای دوباره PARSE نباشد.
مثال 10: مقایسه هزینه PARSE با تبدیل بومی
برای رشته ISO ساده، استفاده از CLR ضرورت ندارد. نسخه پیشنهادی TRY_CONVERT با Style 23 سبکتر، قابل Remoting و برای حجم بالا مناسبتر است.
DECLARE @IsoText varchar(10) = '2026-07-19';
SELECT TRY_CONVERT(date, @IsoText, 23) AS PreferredDate;
-- PARSE(@IsoText AS date USING 'en-US') در این سناریو ضروری نیست.
| روش پیشنهادی | دلیل |
|---|
| TRY_CONVERT با Style 23 | بومی، روشن و معمولاً کمهزینهتر |
نکته کاربردی: PARSE را زمانی انتخاب کنید که واقعاً به قواعد فرهنگی .NET نیاز دارید؛ انتخاب تابع باید بر اساس معنا و حجم کار باشد.
NULL، داده مرزی و اعتبارسنجی
NULL نشانه ناشناخته یا نبود مقدار است و نباید بدون تصمیم کسبوکاری با صفر یا رشته خالی جایگزین شود. در کار با 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 آزمایش کنید.
کاربردهای واقعی
PARSE میتواند در ورود فایل فروش، پاکسازی داده CRM، تبدیل تاریخ قرارداد، ساخت خروجی API، مهاجرت سامانه قدیمی، کنترل فرم کاربر و آمادهسازی Data Warehouse استفاده شود. نقطه مشترک همه سناریوها وجود یک قرارداد روشن میان متن خام و نوع استاندارد است.
در پروژه سازمانی بهتر است منطق تبدیل در View یا گزارشهای متعدد کپی نشود. Procedure ورودی، Pipeline ETL یا لایه سرویس مشترک میتواند قرارداد را متمرکز کند. این تمرکز تست، پایش نرخ خطا، تغییر نسخه و ارائه خدمات پشتیبانی پایگاه داده را بسیار سادهتر میسازد.
سؤالات متداول
پرسش متداول 1: PARSE در SQL Server دقیقاً چه کاری انجام میدهد؟
PARSE مقدار ورودی را به نوع مقصد تبدیل میکند و ویژگی شاخص آن قواعد Culture در .NET است. انتخاب نوع مقصد، طول، precision و scale بخشی از قرارداد داده محسوب میشود و نباید به پیشفرضها واگذار شود.
پرسش متداول 2: خروجی و رفتار خطای PARSE چگونه است؟
خروجی از نوع مقصد اعلامشده خواهد بود. در ورودی ناسازگار خطا میدهد و برای داده کنترلنشده باید اعتبارسنجی یا نسخه TRY در نظر گرفته شود. برای طراحی درست باید NULL واقعی ورودی، شکست تبدیل و مقدار خارج از دامنه را جداگانه پایش کنید.
پرسش متداول 3: آیا یادگیری PARSE برای پروژههای تجاری SQL Server ضروری است؟
بله؛ بسیاری از خطاهای مالی، تاریخی و یکپارچهسازی از تبدیل ضمنی یا نوع مقصد نامناسب ناشی میشوند. آموزش عملی این تابع هزینه رفع خطا و دوبارهکاری گزارشها را کاهش میدهد.
پرسش متداول 4: استفاده حرفهای از PARSE چه ارزش تجاری ایجاد میکند؟
قرارداد تبدیل روشن، داده قابل اعتمادتر، گزارش دقیقتر و فرآیند ورود مقاومتر میسازد. در پروژههای سازمانی میتوان با بازبینی Queryها و مشاوره SQL Server نقاط تبدیل پرریسک را پیش از اختلال شناسایی کرد.
پرسش متداول 5: PARSE را در مقایسه با سایر توابع تبدیل چه زمانی انتخاب کنیم؟
وقتی معنای رشته به Culture واقعی وابسته است این تابع مناسب است؛ برای قالب ثابت معمولاً TRY_CONVERT یا CONVERT سبکتر است.
پرسش متداول 6: برای پیادهسازی PARSE در Procedure موجود چه خدمتی لازم است؟
ابتدا نمونه داده، نوع ستونها، تنظیم زبان Session، حجم ردیف و Plan اجرایی بررسی میشود. سپس میتوان نسخه آزمایشی، تست مرزی و راهکار مهاجرت را در قالب مشاوره یا انجام پروژه SQL Server آماده کرد.
پرسش متداول 7: رایجترین خطا هنگام کار با PARSE چیست؟
انتخاب Culture اشتباه یا حدس زدن Culture از ظاهر متن، خطای اصلی است. متن خام و قرارداد منبع را در تستها نگه دارید.
پرسش متداول 8: PARSE چه اثری بر Performance دارد؟
این تابع به CLR متکی است و روی حجم بالا معمولاً از تبدیلهای بومی هزینه بیشتری دارد. تبدیل را ترجیحاً در مرز ورود یا روی پارامتر انجام دهید.
پرسش متداول 9: بهترین روش استفاده از PARSE چیست؟
نوع مقصد و طول را صریح تعیین کنید، حالتهای NULL و سرریز را تست کنید، شکستها را ثبت کنید و مقدار استاندارد را برای مصرفهای بعدی نگه دارید. قالببندی نمایشی را تا حد امکان به لایه نمایش بسپارید.
پرسش متداول 10: PARSE در کدام نسخههای SQL Server قابل استفاده است؟
این تابع از SQL Server 2012 در دسترس است و در نسخههای جدید SQL Server و Azure SQL نیز پشتیبانی میشود؛ سطح سازگاری و محدودیت Remoting را بررسی کنید.
سؤالات مصاحبه SQL Server
سؤال مصاحبه 1: تفاوت تبدیل ضمنی و PARSE چیست؟
در تبدیل ضمنی موتور بر اساس اولویت انواع تصمیم میگیرد، اما تابع تبدیل قصد و نوع مقصد را صریح میکند. تبدیل ضمنی روی سمت نامناسب Join یا Predicate میتواند هم خطا و هم افت کارایی ایجاد کند.
سؤال مصاحبه 2: PARSE با TRY_CONVERT چه تفاوتی دارد؟
نسخه TRY برای داده کنترلنشده مقاومتر است و شکست معمول را به NULL تبدیل میکند؛ نسخه قطعی برای قرارداد معتبر و Fail-fast مناسب است.
سؤال مصاحبه 3: چرا تبدیل ستون در WHERE ممکن است بد باشد؟
چون عبارت روی ستون میتواند جستوجو را غیر SARGable کند و مانع استفاده مستقیم از کلید مرتب ایندکس شود. معمولاً تبدیل پارامتر یا شرط بازهای Plan بهتری میسازد.
سؤال مصاحبه 4: چگونه شکستهای تبدیل را بدون پنهان کردن خطا مدیریت میکنید؟
متن خام، مقدار استاندارد، وضعیت و علت Reject را جدا ذخیره میکنم؛ نرخ شکست را مانیتور و برای عبور از آستانه هشدار تعریف میکنم. NULL حاصل نباید بیگزارش از محاسبات حذف شود.
سؤال مصاحبه 5: برای تست تبدیل چه حالتهایی لازم است؟
مقدار سالم، NULL، رشته خالی، نویسه یونیکد، حداقل و حداکثر نوع، سرریز، طول بیش از مقصد، تاریخ ناممکن، Culture متفاوت و حجم واقعی باید پوشش داده شوند.
چکلیست نهایی
- نوع مقصد PARSE با دامنه واقعی داده هماهنگ است.
- طول متن، precision، scale یا دقت زمانی صریح تعیین شده است.
- رفتار NULL، ورودی خراب و سرریز با تست پوشش داده شده است.
- هیچ تابع غیرضروری روی ستون ایندکسشده در Predicate اجرا نمیشود.
- خروجی تبدیل ناموفق ثبت، شمارش و برای اصلاح قابل ردیابی است.
- Query روی نسخه هدف SQL Server و با حجم نزدیک تولید آزمایش شده است.
جمعبندی
PARSE زمانی ارزشمند است که با شناخت نوع داده، کیفیت منبع و مسیر مصرف انتخاب شود. مثالهای این مقاله نشان دادند چگونه تبدیل ساده، NULL، داده مرزی، گزارش سازمانی و کارایی را در یک طراحی قابل اعتماد کنار هم قرار دهیم. اصل مهم این است که تبدیل را بخشی از قرارداد داده بدانیم، نه وصلهای برای پوشاندن نوع ستون نامناسب.
برای مقایسه دوباره گزینهها و دسترسی به مقالههای مرتبط، به راهنمای جامع CAST، CONVERT، TRY_CAST، TRY_CONVERT، PARSE و TRY_PARSE بازگردید.