رفع خطای String or binary data would be truncated در SQL Server
هنگام INSERT یا UPDATE ممکن است با یکی از این پیامها روبهرو شوی:
Msg 8152, Level 16, State 30 String or binary data would be truncated. The statement has been terminated.
و در SQL Server 2019 و جدیدتر (سطح سازگاری ۱۵۰ به بالا) پیام دقیقتر:
Msg 2628, Level 16, State 1 String or binary data would be truncated in table 'SchoolDB.dbo.Student', column 'FullName'. Truncated value: 'محمدحسین عبدالرحمانی نژاد ...'.
علتهای رایج
- ستون با طول کم تعریف شده (مثلاً
NVARCHAR(20)) و ورودی بلندتر آمده. - تفاوت
VARCHARوNVARCHARیا اختلاف طول در دو جدول (INSERT ... SELECTاز ستون بلندتر به کوتاهتر). - ستونهای نادرست در
INSERT(ترتیب ستونها جابهجا شده و مقدار بلند در ستون کوتاه مینشیند). - ورودی دارای فاصلههای اضافی یا کاراکترهای ناخواسته.
گام ۱: پیدا کردن ستون مشکلدار
در SQL Server 2019 به بعد (با سطح سازگاری ۱۵۰ یا بالاتر) نام ستون در خود پیام هست. در نسخههای قدیمیتر، طول ستونها و بلندترین مقدار ورودی را مقایسه کن:
-- طول تعریفشدهی ستونهای جدول مقصد SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Student'; -- بلندترین مقدار موجود در دادهی منبع SELECT MAX(LEN(FullName)) AS MaxLen FROM StagingStudent;
اگر دستور از INSERT ... SELECT است، ردیفهای مشکلدار را مستقیم بیاب:
SELECT * FROM StagingStudent WHERE LEN(FullName) > 100; -- ۱۰۰ = طول ستون مقصد
گام ۲: راهحلها
الف) افزایش طول ستون
اگر دادهی بلند معتبر است، طول ستون را زیاد کن:
ALTER TABLE Student ALTER COLUMN FullName NVARCHAR(200) NOT NULL;
ALTER COLUMN روی جدولهای بزرگ قفل میگذارد؛ در ساعت پرترافیک اجرا نکن. اگر ستون NULL نبود، حتماً همان NOT NULL را تکرار کن، وگرنه ستون NULLپذیر میشود.ب) اعتبارسنجی و کوتاه کردن ورودی
اگر کوتاه شدن قابلقبول است (مثلاً توضیحات)، صریحاً و آگاهانه بُر بزن:
INSERT INTO Student (FullName) SELECT LEFT(FullName, 100) FROM StagingStudent;
ج) اعتبارسنجی در برنامه
بهتر است فیلد ورودی در برنامه یا فرم، حداکثر طول (maxlength) داشته باشد تا خطا اصلاً به پایگاهداده نرسد.
انتخاب درست طول ستونها
| نوع داده | توصیه |
|---|---|
| نام و نامخانوادگی | NVARCHAR(100) |
| ایمیل | NVARCHAR(254) |
| شمارهی موبایل | VARCHAR(15) |
| کد ملی | CHAR(10) |
| آدرس | NVARCHAR(300) یا بیشتر |
| متن بلند/توضیحات | NVARCHAR(MAX) |
پیام قدیمیتر یا غیرفعال بودن پیام دقیق
در SQL Server 2017 و قبلتر پیام بدون نام ستون است. برای نسخههای ۲۰۱۶ SP2 و ۲۰۱۷ CU12 به بعد میتوان پیام دقیقتر را با Trace Flag 460 فعال کرد:
DBCC TRACEON (460, -1); -- فقط برای عیبیابی؛ در ۲۰۱۹ به بعد با سطح سازگاری ۱۵۰ پیشفرض است
برای انتخاب نوع داده و طول مناسب، درس انتخاب نوع داده در طراحی را بخوان. اگر خطای دیگری با کلید خارجی داشتی، مقالهی رفع خطای FOREIGN KEY را ببین.
سوالات متداول دربارهی این موضوع
چرا SQL Server قدیمی ستون را نشان نمیدهد؟
در نسخههای قدیمیتر (قبل از SQL Server 2019) پیام فقط میگوید «String or binary data would be truncated» (Msg 8152) بدون نام ستون. از SQL Server 2019 به بعد (با سطح سازگاری پایگاهداده ۱۵۰ یا بالاتر) پیام جدید Msg 2628 نام جدول، ستون و مقدار را میگوید.
آیا میتوانم خطا را نادیده بگیرم و داده بریده شود؟
با SET ANSI_WARNINGS OFF داده بدون خطا بریده میشود، اما این کار خطرناک است چون اطلاعات بیصدا از بین میرود. بهتر است طول ستون را اصلاح کنی یا ورودی را قبل از درج اعتبارسنجی کنی.
VARCHAR(50) یعنی ۵۰ حرف فارسی؟
برای NVARCHAR(50) بله، ۵۰ کاراکتر یونیکد. برای VARCHAR(50) عدد بر حسب بایت است؛ حروف فارسی (بسته به Collation) ممکن است بیش از یک بایت بگیرند. برای متن فارسی NVARCHAR انتخاب کن.
میخوای SQL را از پایه و با تمرین یاد بگیری؟
دورهی رایگان SQLFarsi را با Playground و پروژههای واقعی دنبال کن.
شروع یادگیری