Ответ на DUP, который был закрыт, поэтому отвечайте здесь вместо этого. Этот шаблон можно использовать, если он несколько сложен, но он может быть полезен, когда нетрудно изменить приложение или настроить профилировщик, чтобы увидеть, что происходит. Иногда вам просто нужно, чтобы ошибка распространялась на само приложение, чтобы вы могли видеть прямо из приложения правильное и полезное сообщение об ошибке.
В этих случаях быстрое проникновение в БД с помощью этого решения сэкономит вам много времени. Сохраните его как шаблон и внесите в него быстрые изменения, чтобы решить эту проблему на любом столе.
Проблема
Пример таблицы
create table StringTruncation
(A int, B varchar(10), C nvarchar(5), D nvarchar(max), E datetime)
Пример выписки
insert StringTruncation values
(1, '0123456789', 'abcdef', 'This overflows on C', GETDATE())
страшная бесполезная ошибка
Msg 8152, Level 16, State 4, Line 1
String or binary data would be truncated.
The statement has been terminated.
В примере показаны только 2 столбца, в которых он может переполниться, но представьте, что это будет 20 или 40 столбцов.
Решение
-- First move the table out of the way
exec sp_rename StringTruncation, StringTruncation_;
-- cover it with a query
create view dbo.StringTruncation
with schemabinding
as
select
A,
convert(Nvarchar(max),B) B,
convert(Nvarchar(max),C) C,
D, E
from dbo.StringTruncation_
GO
-- use a trigger to allow INSERTs, with the length checks thrown in
create trigger dbo.trig_ioi_StringTruncation
on StringTruncation
instead of insert
as
set nocount on
declare @offending nvarchar(max)
select TOP 1 @offending = case
when len(C) > 5 then 'Data too long for Column [C] Size 5: ' + C
when len(B) > 10 then 'Data too long for Column [D] Size 10: ' + B
end
from inserted
where len(C) > 5 or len(B) > 10
GO
-- keep good data
if @@rowcount = 0
insert StringTruncation_
select * from inserted
else
raiserror(@offending,16,1)
GO
Проверьте это
insert StringTruncation values
(1, '0s123456789', 'abcde', 'This overflows on C', GETDATE())
Результат
Сообщение 50000, уровень 16, состояние 1, процедура trig_ioi_StringTruncation, строка 18
Данные слишком длинные для столбца [D]. Размер 10: 0s123456789
(Затронут 1 ряд)
Примечания
- Требуется зеркальный триггер для ОБНОВЛЕНИЙ
- В настоящее время он будет сообщать только о первом поврежденном столбце записи. Можно сообщить более одного столбца записи, но я считаю, что это на самом деле контрпродуктивно.