آموزش تابع CONVERT در SQL Server و کدهای Style
مقدمه
تابع CONVERT یکی از ابزارهای مهم تبدیل داده در Microsoft SQL Server است. تبدیل نوع فقط تغییر ظاهر مقدار نیست؛ نوع مقصد بر مقایسه، دقت محاسبه، مرتبسازی، مصرف حافظه و امکان استفاده از ایندکس اثر میگذارد. در این راهنما از مثال ساده آغاز میکنیم و سپس سناریوهای پاکسازی داده، گزارشگیری، مدیریت NULL و بهینهسازی را بررسی میکنیم.
اگر نوع ستون با معنای واقعی داده هماهنگ باشد، نیاز به تبدیل در Queryها کمتر و طراحی پایدارتر میشود. با این حال در مرزهای سامانه مانند فایل ورودی، API، گزارش متنی و اتصال به نرمافزار قدیمی، استفاده آگاهانه از CONVERT ضروری است. هر مثال این مقاله کامل، مستقل و دارای خروجی مورد انتظار است تا بتوانید رفتار را در محیط آزمایشی بررسی کنید.
برای دیدن جایگاه این تابع در کنار پنج گزینه دیگر، راهنمای جامع توابع تبدیل داده در SQL Server را نیز مطالعه کنید. آن مقاله یک جدول تصمیم دارد و نشان میدهد چه زمانی تبدیل استاندارد، نسخه امن، Style یا Culture انتخاب مناسبتری است.
تعریف تابع CONVERT
CONVERT تابع اختصاصی و پرکاربرد SQL Server برای تبدیل صریح نوع داده است. تفاوت مهم آن با CAST، آرگومان اختیاری style است که شکل خواندن یا نمایش تاریخ، زمان، عدد پولی، float و داده باینری را کنترل میکند. این قابلیت در گزارشها و یکپارچهسازی سامانههای قدیمی ارزش زیادی دارد.
این تابع در ورودی ناسازگار معمولاً خطا ایجاد میکند؛ بنابراین برای داده خام باید مرحله اعتبارسنجی یا مدیریت خطا طراحی شود. آرگومان Style باید بخشی از قرارداد ورودی یا خروجی باشد و استفاده از کدهای مبهم بدون توضیح توصیه نمیشود.
نحو یا Syntax
-- Syntax
CONVERT ( data_type [ ( length ) ], expression [ , style ] )
پارامترها
- data_type: نوع داده مقصد که در ابتدای تابع نوشته میشود.
- expression: مقدار یا عبارتی که باید تبدیل شود.
- style: عدد اختیاری برای تعیین قالب ورودی یا خروجی؛ معنی آن به نوع داده وابسته است.
نوع خروجی و رفتار خطا
خروجی از نوع data_type تعیینشده است. Style نوع خروجی را عوض نمیکند، اما نمایش رشتهای یا شیوه تفسیر مقدار ورودی را تغییر میدهد. تبدیل نامعتبر در CONVERT خطا تولید میکند.
| معیار | راهنمای استفاده |
|---|
| نوع مبدأ | نوع واقعی عبارت و اولویت انواع SQL Server را بررسی کنید. |
| نوع مقصد | طول، precision، scale و دقت زمانی را صریح انتخاب کنید. |
| داده نامعتبر | پیش از تبدیل کیفیت را تضمین یا خطا را در مرز مناسب مدیریت کنید. |
| حجم بالا | از اجرای تابع روی ستون ایندکسشده در Predicate پرهیز کنید. |
چه زمانی از CONVERT استفاده کنیم؟
این تابع برای تبدیلهایی مناسب است که علاوه بر نوع مقصد، Style مشخص تاریخ، زمان یا باینری اهمیت دارد. اگر داده در اختیار شماست، اصلاح نوع ستون در طراحی پایگاه داده معمولاً بهتر از تکرار تبدیل در همه Queryها خواهد بود.
تبدیل را نزدیک مرزی انجام دهید که داده از متن یا سامانه خارجی وارد مدل استاندارد میشود. مقدار خام را برای حسابرسی حفظ کنید، مقدار تبدیلشده را در نوع درست بنویسید و وضعیت اعتبارسنجی را جدا نگه دارید. این الگو سبب میشود گزارشها سادهتر، ایندکسها مؤثرتر و مسئولیت کیفیت داده شفافتر باشد.
در عملیات مالی، precision و scale را از قبل محاسبه کنید. در متن فارسی nvarchar و پیشوند N را بهکار ببرید. برای تاریخوزمان نیز میان date، datetime2 و datetimeoffset تفاوت بگذارید؛ تبدیل یک زمان محلی به متن، آن را خودکار به UTC تبدیل نمیکند و Offset باید در قرارداد سامانه مشخص باشد.
مثالهای عملی
مثال 1: تبدیل متن به عدد صحیح
نحو CONVERT نوع مقصد را پیش از عبارت میآورد. در تبدیلهای ساده نتیجه آن با CAST یکسان است و انتخاب میان آنها بیشتر به استاندارد کدنویسی تیم وابسته خواهد بود.
SELECT CONVERT(int, '2048') AS ConvertedNumber;
نکته کاربردی: برای کد قابلحمل میان موتورهای پایگاه داده CAST استانداردتر است؛ در کد ویژه SQL Server استفاده از CONVERT نیز روشن و معتبر است.
مثال 2: نمایش تاریخ با Style برابر 23
Style شماره 23 تاریخ میلادی را به شکل قطعی yyyy-mm-dd تولید میکند. این قالب برای خروجی متنی ماشینخوان و گزارشهای بدون بخش زمان مناسب است.
DECLARE @D date = '2026-07-19';
SELECT CONVERT(char(10), @D, 23) AS IsoDateText;
نکته کاربردی: خروجی این مثال متن است، نه date؛ برای مرتبسازی و محاسبه، مقدار اصلی تاریخ را حفظ و فقط در مرز نمایش تبدیل کنید.
مثال 3: تولید تاریخ و زمان ISO با Style برابر 126
Style شماره 126 قالب ISO 8601 با حرف T را میسازد. استفاده از datetime2 و طول کافی باعث میشود ثانیهها و بخش اعشاری موردنیاز بهصورت قابل پیشبینی نمایش داده شوند.
DECLARE @D datetime2(3) = '2026-07-19T14:05:09.125';
SELECT CONVERT(varchar(23), @D, 126) AS IsoDateTime;
| IsoDateTime |
|---|
| 2026-07-19T14:05:09.125 |
نکته کاربردی: برای تبادل میان سامانهها Offset را نیز در قرارداد مشخص کنید؛ Style فقط شکل متن را تعیین میکند و منطقه زمانی اضافه نمیکند.
مثال 4: خواندن تاریخ بریتانیایی با Style 103
رشته 19/07/2026 در قالب روز، ماه و سال نوشته شده است. اعلام Style 103 وابستگی تبدیل به تنظیمات زبان Session را کاهش میدهد و قصد فرمت ورودی را آشکار میکند.
SELECT CONVERT(date, '19/07/2026', 103) AS ParsedDate;
نکته کاربردی: برای دادههای ورودی کنترلنشده TRY_CONVERT با همین Style بهتر است، زیرا یک ردیف نامعتبر کل دسته را متوقف نمیکند.
مثال 5: قالببندی مبلغ پولی با Style
در تبدیل money به varchar، Style شماره 1 جداکننده هزارگان و دو رقم اعشار ایجاد میکند. نمونه برای خروجی یک گزارش قدیمی مفید است، هرچند قالببندی نهایی معمولاً بهتر است در لایه نمایش انجام شود.
DECLARE @Amount money = 1234567.5;
SELECT CONVERT(varchar(30), @Amount, 1) AS DisplayAmount;
| DisplayAmount |
|---|
| 1,234,567.50 |
نکته کاربردی: نوع money و قالب متنی را برای محاسبات بعدی به کار نبرید؛ برای منطق مالی معمولاً decimal با دقت مشخص انتخاب مناسبتری است.
مثال 6: تبدیل باینری به Hex با Style 2
Style شماره 2 داده varbinary را بدون پیشوند 0x به رشته هگزادسیمال تبدیل میکند. این روش برای ثبت شناسه باینری در Log یا مقایسه انسانی خروجی مفید است.
DECLARE @Bytes varbinary(4) = 0x4F414931;
SELECT CONVERT(varchar(8), @Bytes, 2) AS HexText;
نکته کاربردی: برای بازگرداندن متن Hex به varbinary نیز Style را آگاهانه تعیین کنید؛ Styleهای 1 و 2 درباره وجود پیشوند 0x قواعد متفاوت دارند.
مثال 7: رفتار CONVERT با NULL در گزارش
ورودی NULL پس از تبدیل نیز NULL میماند. در این نمونه ISNULL مقدار نمایشی «ثبت نشده» را فقط برای خروجی گزارش جایگزین میکند و مقدار واقعی پایگاه داده دستنخورده است.
DECLARE @PaidAt datetime2 = NULL;
SELECT ISNULL(CONVERT(nvarchar(19), @PaidAt, 120), N'ثبت نشده') AS PaidAtText;
نکته کاربردی: اگر عبارت جایگزین فارسی است، مقصد nvarchar و رشته N ضروریاند تا تبدیل کدپیج سبب خرابی نویسهها نشود.
مثال 8: استفاده از Style در جدول نمونه سفارش
جدول نمونه چند زمان ثبت را نگه میدارد و CONVERT فقط در SELECT نسخه نمایشی میسازد. مرتبسازی همچنان بر اساس مقدار datetime2 انجام میشود تا ترتیب زمانی درست باشد.
DECLARE @Orders TABLE (OrderId int, CreatedAt datetime2(0));
INSERT INTO @Orders VALUES
(10,'2026-07-19T09:15:00'),(11,'2026-07-20T17:45:00');
SELECT OrderId, CONVERT(char(19), CreatedAt, 120) AS CreatedText
FROM @Orders
ORDER BY CreatedAt;
| OrderId | CreatedText |
|---|
| 10 | 2026-07-19 09:15:00 |
| 11 | 2026-07-20 17:45:00 |
نکته کاربردی: مرتبسازی بر متن قالببندیشده میتواند در بعضی Styleها نتیجه نادرست بدهد؛ ORDER BY را روی ستون زمانی اصلی انجام دهید.
مثال 9: حذف ابهام Style در تاریخ متنی
فرمتهایی مانند 07/08/2026 بدون قرارداد مشخص میتوانند دو معنای متفاوت داشته باشند. نسخه اصلاحشده با رشته ISO و Style 23 ابهام را از بین میبرد و نگهداری کد را ساده میکند.
-- روش روشن و مستقل از زبان Session
SELECT CONVERT(date, '2026-08-07', 23) AS UnambiguousDate;
| UnambiguousDate |
|---|
| 2026-08-07 |
نکته کاربردی: در API و فایل تبادلی، ISO 8601 را قرارداد کنید. استفاده از Style درست خوب است، اما حذف ابهام از منبع داده راهحل بنیادیتری محسوب میشود.
مثال 10: فیلتر کارا بدون تبدیل ستون تاریخ
تبدیل CreatedAt به رشته در WHERE روش رایجی برای جستوجوی روز است، اما ایندکس را کماثر میکند. در نسخه مناسب، مرز شروع یکبار تبدیل و ستون بهصورت خام مقایسه میشود.
DECLARE @DateText char(10) = '2026-07-19';
DECLARE @Start date = CONVERT(date, @DateText, 23);
SELECT OrderId, CreatedAt
FROM dbo.Orders
WHERE CreatedAt >= @Start
AND CreatedAt < DATEADD(day, 1, @Start);
| بخش تبدیلشده | نتیجه کارایی |
|---|
| پارامتر ورودی | امکان استفاده از ایندکس CreatedAt |
نکته کاربردی: CONVERT را بیرون مسیر هر ردیف اجرا کنید. تبدیل یک پارامتر بسیار ارزانتر از تبدیل میلیونها مقدار ستون در هنگام جستوجو است.
NULL، داده مرزی و اعتبارسنجی
NULL نشانه ناشناخته یا نبود مقدار است و نباید بدون تصمیم کسبوکاری با صفر یا رشته خالی جایگزین شود. در کار با CONVERT ابتدا NULL اصلی را بررسی کنید، سپس شکست تبدیل را بسنجید و در نهایت قواعد دامنه مانند حداقل، حداکثر و تعداد رقم را اعمال کنید. تبدیل شدن یک متن به عدد یا تاریخ فقط اعتبار نحوی و نوعی را نشان میدهد، نه الزاماً معتبر بودن آن برای فرآیند سازمانی.
دادههای مرزی شامل بزرگترین عدد مجاز، متن با طول دقیق مقصد، زمانهای نزدیک تغییر روز، تاریخ ناممکن، نویسههای یونیکد و رشته دارای فاصله هستند. برای هرکدام تست خودکار بنویسید و نتیجه را در نسخه هدف SQL Server کنترل کنید. همچنین Collation، زبان Session و DATEFORMAT را در تست یکپارچگی نادیده نگیرید.
خطاهای رایج
- اعتماد به تبدیل ضمنی و نادیده گرفتن اولویت نوعهای داده در عبارت یا Join.
- ننوشتن طول varchar یا nvarchar و بریده شدن خروجی در یکی از مسیرهای اجرا.
- انتخاب decimal با precision ناکافی و ایجاد سرریز یا گرد شدن ناخواسته.
- استفاده از Style مبهم یا ناسازگار با قرارداد واقعی منبع.
- قرار دادن تابع تبدیل روی ستون ایندکسشده در WHERE و دشوار کردن Index Seek.
- نادیده گرفتن خروجی NULL نسخههای TRY و گزارش کردن جمع ناقص بهعنوان نتیجه کامل.
رفع خطا فقط با پیچیدن عبارت در یک تابع TRY کامل نمیشود. باید مالک داده خراب، مسیر اصلاح، حد قابل قبول نرخ شکست و رفتار تراکنش مشخص باشد. سامانه مقاوم خطا را مدیریت میکند، اما آن را پنهان نمیکند.
نکات Performance و بهینهسازی
هزینه یک تبدیل منفرد معمولاً کم است، ولی ضرب آن در میلیونها ردیف محسوس میشود. توابع بومی تبدیل معمولاً سبکاند، اما محل اجرای آنها در Plan اهمیت زیادی دارد. Actual Execution Plan، زمان CPU، تعداد خواندن منطقی و تخمین Cardinality را پیش و پس از تغییر مقایسه کنید.
اگر Predicate روی CAST یا CONVERT ستون نوشته شود، موتور ممکن است نتواند از ترتیب ایندکس بهطور مستقیم استفاده کند. بهجای آن پارامتر را به نوع ستون تبدیل کنید، برای تاریخ از بازه نیمهباز استفاده کنید یا مقدار استاندارد را در ستون مناسب ذخیره کنید. ستون محاسباتی Persisted و ایندکس فیلترشده گاهی مفیدند، اما باید قطعی بودن عبارت و هزینه نگهداری آنها ارزیابی شود.
در فرآیند ETL، تبدیل و اعتبارسنجی را یکبار در Staging انجام دهید. سپس ردیف سالم را به جدول نهایی و ردیف خراب را با علت و متن خام به Reject بفرستید. این طراحی هم گزارش را سریع میکند و هم امکان حسابرسی و اصلاح دستهای را فراهم میآورد.
بهترین روشها
- نوع مقصد را از مدل کسبوکار انتخاب کنید، نه از یک نمونه محدود داده.
- طول متن و precision و scale عدد را همیشه صریح بنویسید.
- قالب تاریخ ورودی را ISO یا Style مشخص و مستند نگه دارید.
- NULL اصلی، شکست تبدیل و نقض دامنه را سه وضعیت جدا در نظر بگیرید.
- تبدیل را روی پارامتر یا هنگام ورود انجام دهید و ستون ایندکسشده را در شرط دستنخورده نگه دارید.
- برای متن فارسی از nvarchar و رشتههای N استفاده کنید.
- نتیجه و Plan را با داده واقعی و نسخه هدف SQL Server آزمایش کنید.
کاربردهای واقعی
CONVERT میتواند در ورود فایل فروش، پاکسازی داده CRM، تبدیل تاریخ قرارداد، ساخت خروجی API، مهاجرت سامانه قدیمی، کنترل فرم کاربر و آمادهسازی Data Warehouse استفاده شود. نقطه مشترک همه سناریوها وجود یک قرارداد روشن میان متن خام و نوع استاندارد است.
در پروژه سازمانی بهتر است منطق تبدیل در View یا گزارشهای متعدد کپی نشود. Procedure ورودی، Pipeline ETL یا لایه سرویس مشترک میتواند قرارداد را متمرکز کند. این تمرکز تست، پایش نرخ خطا، تغییر نسخه و ارائه خدمات پشتیبانی پایگاه داده را بسیار سادهتر میسازد.
سؤالات متداول
پرسش متداول 1: CONVERT در SQL Server دقیقاً چه کاری انجام میدهد؟
CONVERT مقدار ورودی را به نوع مقصد تبدیل میکند و ویژگی شاخص آن آرگومان Style در SQL Server است. انتخاب نوع مقصد، طول، precision و scale بخشی از قرارداد داده محسوب میشود و نباید به پیشفرضها واگذار شود.
پرسش متداول 2: خروجی و رفتار خطای CONVERT چگونه است؟
خروجی از نوع مقصد اعلامشده خواهد بود. در ورودی ناسازگار خطا میدهد و برای داده کنترلنشده باید اعتبارسنجی یا نسخه TRY در نظر گرفته شود. برای طراحی درست باید NULL واقعی ورودی، شکست تبدیل و مقدار خارج از دامنه را جداگانه پایش کنید.
پرسش متداول 3: آیا یادگیری CONVERT برای پروژههای تجاری SQL Server ضروری است؟
بله؛ بسیاری از خطاهای مالی، تاریخی و یکپارچهسازی از تبدیل ضمنی یا نوع مقصد نامناسب ناشی میشوند. آموزش عملی این تابع هزینه رفع خطا و دوبارهکاری گزارشها را کاهش میدهد.
پرسش متداول 4: استفاده حرفهای از CONVERT چه ارزش تجاری ایجاد میکند؟
قرارداد تبدیل روشن، داده قابل اعتمادتر، گزارش دقیقتر و فرآیند ورود مقاومتر میسازد. در پروژههای سازمانی میتوان با بازبینی Queryها و مشاوره SQL Server نقاط تبدیل پرریسک را پیش از اختلال شناسایی کرد.
پرسش متداول 5: CONVERT را در مقایسه با سایر توابع تبدیل چه زمانی انتخاب کنیم؟
وقتی کنترل Style بهویژه برای تاریخ یا باینری لازم است این تابع بر CAST برتری دارد؛ در تبدیل ساده CAST گویاتر و استانداردتر است.
پرسش متداول 6: برای پیادهسازی CONVERT در Procedure موجود چه خدمتی لازم است؟
ابتدا نمونه داده، نوع ستونها، تنظیم زبان Session، حجم ردیف و Plan اجرایی بررسی میشود. سپس میتوان نسخه آزمایشی، تست مرزی و راهکار مهاجرت را در قالب مشاوره یا انجام پروژه SQL Server آماده کرد.
پرسش متداول 7: رایجترین خطا هنگام کار با CONVERT چیست؟
استفاده از Style مبهم یا تبدیل ستون ایندکسشده در WHERE بسیار رایج است. متن خام و قرارداد منبع را در تستها نگه دارید.
پرسش متداول 8: CONVERT چه اثری بر Performance دارد؟
خود تبدیل روی تعداد کم ارزان است، اما اجرای آن برای هر ردیف بزرگ یا روی ستون شرط میتواند CPU را افزایش و Index Seek را محدود کند. تبدیل را ترجیحاً در مرز ورود یا روی پارامتر انجام دهید.
پرسش متداول 9: بهترین روش استفاده از CONVERT چیست؟
نوع مقصد و طول را صریح تعیین کنید، حالتهای NULL و سرریز را تست کنید، شکستها را ثبت کنید و مقدار استاندارد را برای مصرفهای بعدی نگه دارید. قالببندی نمایشی را تا حد امکان به لایه نمایش بسپارید.
پرسش متداول 10: CONVERT در کدام نسخههای SQL Server قابل استفاده است؟
این تابع در نسخههای قدیمی و جدید SQL Server در دسترس است و برای سازگاری دقیق باید نوعهای مقصد و رفتار نسخه هدف در محیط آزمایشی کنترل شود.
سؤالات مصاحبه SQL Server
سؤال مصاحبه 1: تفاوت تبدیل ضمنی و CONVERT چیست؟
در تبدیل ضمنی موتور بر اساس اولویت انواع تصمیم میگیرد، اما تابع تبدیل قصد و نوع مقصد را صریح میکند. تبدیل ضمنی روی سمت نامناسب Join یا Predicate میتواند هم خطا و هم افت کارایی ایجاد کند.
سؤال مصاحبه 2: CONVERT با TRY_CONVERT چه تفاوتی دارد؟
نسخه TRY برای داده کنترلنشده مقاومتر است و شکست معمول را به NULL تبدیل میکند؛ نسخه قطعی برای قرارداد معتبر و Fail-fast مناسب است.
سؤال مصاحبه 3: چرا تبدیل ستون در WHERE ممکن است بد باشد؟
چون عبارت روی ستون میتواند جستوجو را غیر SARGable کند و مانع استفاده مستقیم از کلید مرتب ایندکس شود. معمولاً تبدیل پارامتر یا شرط بازهای Plan بهتری میسازد.
سؤال مصاحبه 4: چگونه شکستهای تبدیل را بدون پنهان کردن خطا مدیریت میکنید؟
متن خام، مقدار استاندارد، وضعیت و علت Reject را جدا ذخیره میکنم؛ نرخ شکست را مانیتور و برای عبور از آستانه هشدار تعریف میکنم. NULL حاصل نباید بیگزارش از محاسبات حذف شود.
سؤال مصاحبه 5: برای تست تبدیل چه حالتهایی لازم است؟
مقدار سالم، NULL، رشته خالی، نویسه یونیکد، حداقل و حداکثر نوع، سرریز، طول بیش از مقصد، تاریخ ناممکن، Culture متفاوت و حجم واقعی باید پوشش داده شوند.
چکلیست نهایی
- نوع مقصد CONVERT با دامنه واقعی داده هماهنگ است.
- طول متن، precision، scale یا دقت زمانی صریح تعیین شده است.
- رفتار NULL، ورودی خراب و سرریز با تست پوشش داده شده است.
- هیچ تابع غیرضروری روی ستون ایندکسشده در Predicate اجرا نمیشود.
- خروجی تبدیل ناموفق ثبت، شمارش و برای اصلاح قابل ردیابی است.
- Query روی نسخه هدف SQL Server و با حجم نزدیک تولید آزمایش شده است.
جمعبندی
CONVERT زمانی ارزشمند است که با شناخت نوع داده، کیفیت منبع و مسیر مصرف انتخاب شود. مثالهای این مقاله نشان دادند چگونه تبدیل ساده، NULL، داده مرزی، گزارش سازمانی و کارایی را در یک طراحی قابل اعتماد کنار هم قرار دهیم. اصل مهم این است که تبدیل را بخشی از قرارداد داده بدانیم، نه وصلهای برای پوشاندن نوع ستون نامناسب.
برای مقایسه دوباره گزینهها و دسترسی به مقالههای مرتبط، به راهنمای جامع CAST، CONVERT، TRY_CAST، TRY_CONVERT، PARSE و TRY_PARSE بازگردید.