Подтвердить что ты не робот

Почему "строковые или двоичные данные будут усечены" более описательной ошибкой?

Чтобы начать: я понимаю, что означает эта ошибка - я не пытаюсь разрешить его экземпляр.

Эта ошибка, как правило, трудно устранить, поскольку если вы вставляете миллион строк в таблицу шириной 100 колонок, практически нет способа определить, какой столбец какой строки вызывает ошибку - вам нужно изменить свой процесс на вставляйте по одной строке за раз, а затем посмотрите, с какой ошибкой. Это боль, мягко говоря.

Есть ли причина, по которой ошибка выглядит не так?

String or Binary data would be truncated
Error inserting value "Some 18 char value" into SomeTable.SomeColumn VARCHAR(10)

Это значительно облегчило бы найти и исправить значение, если не сама таблица. Если просмотр данных таблицы является проблемой безопасности, возможно, что-то общее, например, задание длины попытки и имя столбца с ошибкой?

4b9b3361

Ответ 1

Оказывается, для этого в MS Connect есть открытый "запрос функции" - я бы посоветовал вам проголосовать за него, если вы хотите изменить функциональность.

https://connect.microsoft.com/SQLServer/feedback/details/339410/

ДОБАВЛЕНО:

На самом деле выглядит так, что есть еще один запрос на эту же функцию (хотя и плохо названную), которая была выдающейся после разработки Yukon в 2005 году, и я призываю людей голосовать за них:

https://connect.microsoft.com/SQLServer/feedback/details/125347/

Обновление 2016

Кажется, Microsoft попыталась удалить доказательства этой ошибки истинного возраста. Справедливо. Найдите старый сайт, архивированный здесь.

Ответ 2

После того, как я не нашел приемлемого ответа, я придумал следующее:

  • Получить запрос, вызывающий проблемы (вы также можете использовать SQL Profiler, если у вас нет источника)
  • Удалите все предложения WHERE и другие несущественные части, пока вы в основном не останетесь с элементами SELECT и FROM
  • Добавить WHERE 0 = 1 (это будет выбирать только структуру таблицы)
  • Добавить INTO [MyTempTable] непосредственно перед предложением FROM

У вас должно получиться что-то вроде

SELECT
 Col1, Col2, ..., [ColN]
INTO [MyTempTable]
FROM
  [Tables etc.]
WHERE 0 = 1

Это создаст таблицу MyTempTable в вашей БД, которую вы можете сравнить с вашей целевой структурой таблицы, чтобы увидеть, где они отличаются, то есть вы можете сравнить столбцы в обеих таблицах.

EDIT: вы можете сравнить типы данных и размеры столбцов каждого столбца в исходной таблице и MyTempTable, чтобы увидеть, где они различаются. Все имена столбцов в вашей новой таблице будут такими же, как и старые, а также типы данных и размеры будет таким же ИСКЛЮЧЕНИЕМ, если столбец-нарушитель. Другими словами, с этим запросом SQL автоматически создаст столбцы, которые достаточно велики для обработки максимально возможной записи из исходной таблицы

Ответ 3

Отвечая на DUP, который закрылся, поэтому ответ здесь. Этот шаблон может быть использован, если он несколько разработан, но может быть полезен, когда нет необходимости изменять приложение или настраивать профилировщик, чтобы увидеть, что происходит. Иногда вам просто нужна ошибка для распространения на APP, поэтому вы можете видеть прямо из APP, правильное и полезное сообщение об ошибке.

В этих случаях быстрый вывод в БД с помощью этого решения сэкономит вам много времени. Сохраните его как шаблон и внесите в него быстрые изменения, чтобы решить эту проблему в любой таблице.

Проблема

Пример таблицы

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())

Результат

Msg 50000, уровень 16, состояние 1, процедура trig_ioi_StringTruncation, строка 18
Данные слишком длинны для столбца [D] Размер 10: 0s123456789

(Затронуты 1 строка (ы))

Примечания

  • Для UPDATEs требуется зеркальный триггер
  • В настоящий момент он будет только сообщать о первом столбце записи оскорбления. Можно сообщить более одного столбца записи, но я считаю, что это действительно контрпродуктивно.

Ответ 4

Microsoft ленив?

Вам, кстати, не нужно пробовать каждую вставку строки отдельно. Просто введите запрос max (len (field)) для каждого текстового столбца, начиная с тех, которые, как вы подозреваете, могут быть виновниками.

Ответ 5

Короткий ответ: Вот как это.

Дольше ответ: Я мог бы увидеть значение при показе номера строки и столбца, возможно, но, вероятно, не имеет смысла показывать фактическую усеченную информацию. С сценарием VARCHAR (10) это, вероятно, не имеет большого значения, но чрезмерно большие данные будут полезными. Но, надеюсь, никто здесь не вставляет ничего больше, чем может VARCHAR (MAX);)

Ответ 6

Описательные сообщения об ошибках в программных системах так же хороши, как и несуществующие.

Это не только для СУБД, но и для любого вида программного обеспечения, которое можно себе представить.

Я думаю, что основная причина заключается в том, что "хорошие описательные сообщения об ошибках" требуют слишком много времени для реализации. Это не входит в среднюю культуру разработчиков программного обеспечения, чтобы тратить много времени на размышления о том, "какая информация хочет, хочет ли пользователь увидеть, возникает ли это конкретное исключение"? Программисты, которые должны записать код для предоставления "хороших описательных сообщений об ошибках", видят только стоимость (их время), а не выгоду.

Одно из последних сообщений об ошибках, которые я получил от программной системы: "Произошло что-то неправильное. Повторите попытку позже". Не шутите.

Ответ 7

У меня тоже была эта ошибка, но я обнаружил, что вызывает:

<option>description</option>  <-- this is not error but is wrong
<option value="option1">option1</option>
<option value="option2">option2</option>
<option value="option3">option3</option> 

Мое приложение MVC извлекает "значение" как пустую строку ant, которая вызывает исключение