خانه/ وبلاگ/ خطای String or binary data would be truncated
خطاهای رایج SQL

رفع خطای String or binary data would be truncated در SQL Server

خطاهای رایج SQL ۵ آبان ۱۴۰۵ 8 دقیقه مطالعه

هنگام INSERT یا UPDATE ممکن است با یکی از این پیام‌ها روبه‌رو شوی:

text
Msg 8152, Level 16, State 30
String or binary data would be truncated.
The statement has been terminated.

و در SQL Server 2019 و جدیدتر (سطح سازگاری ۱۵۰ به بالا) پیام دقیق‌تر:

text
Msg 2628, Level 16, State 1
String or binary data would be truncated in table 'SchoolDB.dbo.Student', column 'FullName'.
Truncated value: 'محمدحسین عبدالرحمانی نژاد ...'.
معنی: مقداری که می‌خواهی ذخیره کنی از طول ستون بیشتر است و SQL Server به‌جای بریدن بی‌صدا، خطا می‌دهد.

علت‌های رایج

  • ستون با طول کم تعریف شده (مثلاً NVARCHAR(20)) و ورودی بلندتر آمده.
  • تفاوت VARCHAR و NVARCHAR یا اختلاف طول در دو جدول (INSERT ... SELECT از ستون بلندتر به کوتاه‌تر).
  • ستون‌های نادرست در INSERT (ترتیب ستون‌ها جابه‌جا شده و مقدار بلند در ستون کوتاه می‌نشیند).
  • ورودی دارای فاصله‌های اضافی یا کاراکترهای ناخواسته.

گام ۱: پیدا کردن ستون مشکل‌دار

در SQL Server 2019 به بعد (با سطح سازگاری ۱۵۰ یا بالاتر) نام ستون در خود پیام هست. در نسخه‌های قدیمی‌تر، طول ستون‌ها و بلندترین مقدار ورودی را مقایسه کن:

sql
-- طول تعریف‌شده‌ی ستون‌های جدول مقصد
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 است، ردیف‌های مشکل‌دار را مستقیم بیاب:

sql
SELECT *
FROM StagingStudent
WHERE LEN(FullName) > 100;   -- ۱۰۰ = طول ستون مقصد

گام ۲: راه‌حل‌ها

الف) افزایش طول ستون

اگر داده‌ی بلند معتبر است، طول ستون را زیاد کن:

sql
ALTER TABLE Student ALTER COLUMN FullName NVARCHAR(200) NOT NULL;
ALTER COLUMN روی جدول‌های بزرگ قفل می‌گذارد؛ در ساعت پرترافیک اجرا نکن. اگر ستون NULL نبود، حتماً همان NOT NULL را تکرار کن، وگرنه ستون NULL‌پذیر می‌شود.

ب) اعتبارسنجی و کوتاه کردن ورودی

اگر کوتاه شدن قابل‌قبول است (مثلاً توضیحات)، صریحاً و آگاهانه بُر بزن:

sql
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 فعال کرد:

sql
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 انتخاب کن.

مصطفی موسویسازنده و نویسنده‌ی SQLFarsi. اگر اشتباهی در مقاله دیدی یا پیشنهادی داری، از طریق mousavi.dev خبر بده.

می‌خوای SQL را از پایه و با تمرین یاد بگیری؟

دوره‌ی رایگان SQLFarsi را با Playground و پروژه‌های واقعی دنبال کن.

شروع یادگیری