Меню

Ms sql ошибка символьные или двоичные данные могут быть усечены

CREATE TABLE dbo.CoolPeople(PersonName VARCHAR(20), PrimaryCar VARCHAR(20));
GO
INSERT INTO dbo.CoolPeople(PersonName, PrimaryCar)
VALUES ('Baby', '2006 Subaru Impreza WRX GD');
GO

Машина Baby длиннее, чем 20 символов, поэтому при выполнении оператора INSERT получаем ошибку:

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

Это засада, поскольку у нас нет идей относительно того, какое поле вызвало проблемы! Это особенно ужасно, когда вы пытаетесь вставить множество строк.

Чтобы пофиксить ошибку, включите флаг трассировки 460

Флаг трассировки 460 был введен в SQL Server Sevice Pack 2, Cummulative Update 6, и в SQL Server 2017. (Вы можете найти и загрузить последние обновления с SQLServerUpdates.com.) Вы можете включить флаг на уровне запроса, например:

INSERT INTO dbo.CoolPeople(PersonName, PrimaryCar)
VALUES ('Baby', '2006 Subaru Impreza WRX GD')
OPTION (QUERYTRACEON 460);
GO

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

Msg 2628, Level 16, State 1, Line 9
String or binary data would be truncated in
table 'StackOverflow2013.dbo.CoolPeople', column 'PrimaryCar'.
Truncated value: '2006 Subaru Impreza '.

Вы можете включить этот флаг трассировки как на уровне запроса (в нашем примере выше), так и на уровне сервера:

DBCC TRACEON(460, -1);
GO

Этот оператор включает его для всех, а не только для вас — поэтому сначала договоритесь со своей командой разработчиков, прежде чем включать его. Это изменит номер ошибки 8152 на 2628 (как показано выше), означающее, что если вы строили обработку ошибок на основании этих номеров, вы сразу получите другое поведение.

Я любитель включения этого флага трассировки на время отладки и изучения, но как только обнаруживаю источник проблем, выключаю его, снова выполнив команду:

DBCC TRACEON(460, -1);
GO

В нашем случае, как только мы идентифицировали избыточную длину машины Baby, необходимо либо изменить название машины, либо изменить тип данных в нашей таблице, чтобы сделать размер столбца больше. Можно также предварительно обрабатывать данные, явно отсекая избыточные символы. Мастерская по разборке данных, если хотите.

Не оставляйте этот флаг включенным

По крайней мере, имеется связанный с этим один баг в SQL Server 2017 CU13: табличные переменные будут выбрасывать ошибки, говорящие, что их содержимое усекается, даже если никакие данные не вставляются в них.

Вот простой скрипт, чтобы проверить, пофиксили ли это поведение:

CREATE OR ALTER PROC dbo.Repro @BigString VARCHAR(8000) AS
BEGIN
DECLARE @Table TABLE ( SmallString VARCHAR(128) )
IF ( 1 = 0 )
/* Это никогда не выполняется */
INSERT INTO @Table ( SmallString )
VALUES(@BigString)
OPTION (QUERYTRACEON 460)
END
GO
DECLARE @BigString VARCHAR(8000) = REPLICATE('blah',100)
EXEC dbo.Repro @BigString
GO

SQL Server 2017 CU13 всё еще сообщает об усечении строки, даже если строка не вставляется:

Переключение с табличной переменной на временную таблицу приводит к ожидаемому поведению:

Это замечательный пример, почему не следует использовать флаги трассировки по умолчанию. Конечно, они могут пофиксить проблемы, но они также могу вызвать непредсказуемое или нежелательное поведение. (И, вообще, я не фанат табличных переменных.)

Содержание

  1. SQL-Ex blog
  2. Как исправить ошибку «Символьные или двоичные данные могут быть усечены»
  3. Чтобы пофиксить ошибку, включите флаг трассировки 460
  4. Не оставляйте этот флаг включенным
  5. Обратные ссылки
  6. Комментарии
  7. Sql server 8152 error
  8. Answered by:
  9. Question
  10. Заметки системного администратора Windows Server
  11. Поиск по этому блогу
  12. Ошибка Microsoft SQL Server: SQL SERVER-Msg 8152, Уровень 16, состояние 14-строковые или двоичные данные будут усечены
  13. Подробности ошибки:
  14. Фактическое сообщение об ошибке:
  15. Решение:
  16. Sql server 8152 error
  17. Вопрос
  18. Ответы
  19. Все ответы

SQL-Ex blog

Новости сайта «Упражнения SQL», статьи и переводы

Как исправить ошибку «Символьные или двоичные данные могут быть усечены»

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

Машина Baby длиннее, чем 20 символов, поэтому при выполнении оператора INSERT получаем ошибку:

Это засада, поскольку у нас нет идей относительно того, какое поле вызвало проблемы! Это особенно ужасно, когда вы пытаетесь вставить множество строк.

Чтобы пофиксить ошибку, включите флаг трассировки 460

Флаг трассировки 460 был введен в SQL Server Sevice Pack 2, Cummulative Update 6, и в SQL Server 2017. (Вы можете найти и загрузить последние обновления с SQLServerUpdates.com.) Вы можете включить флаг на уровне запроса, например:

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

Вы можете включить этот флаг трассировки как на уровне запроса (в нашем примере выше), так и на уровне сервера:

Этот оператор включает его для всех, а не только для вас — поэтому сначала договоритесь со своей командой разработчиков, прежде чем включать его. Это изменит номер ошибки 8152 на 2628 (как показано выше), означающее, что если вы строили обработку ошибок на основании этих номеров, вы сразу получите другое поведение.

Я любитель включения этого флага трассировки на время отладки и изучения, но как только обнаруживаю источник проблем, выключаю его, снова выполнив команду:

В нашем случае, как только мы идентифицировали избыточную длину машины Baby, необходимо либо изменить название машины, либо изменить тип данных в нашей таблице, чтобы сделать размер столбца больше. Можно также предварительно обрабатывать данные, явно отсекая избыточные символы. Мастерская по разборке данных, если хотите.

Не оставляйте этот флаг включенным

По крайней мере, имеется связанный с этим один баг в SQL Server 2017 CU13: табличные переменные будут выбрасывать ошибки, говорящие, что их содержимое усекается, даже если никакие данные не вставляются в них.

Вот простой скрипт, чтобы проверить, пофиксили ли это поведение:

SQL Server 2017 CU13 всё еще сообщает об усечении строки, даже если строка не вставляется:

Переключение с табличной переменной на временную таблицу приводит к ожидаемому поведению:

Это замечательный пример, почему не следует использовать флаги трассировки по умолчанию. Конечно, они могут пофиксить проблемы, но они также могу вызвать непредсказуемое или нежелательное поведение. (И, вообще, я не фанат табличных переменных.)

Обратные ссылки

Нет обратных ссылок

Комментарии

Показывать комментарии Как список | Древовидной структурой

Автор не разрешил комментировать эту запись

Источник

Sql server 8152 error

This forum has migrated to Microsoft Q&A. Visit Microsoft Q&A to post new questions.

Answered by:

Question

I’ve been working with a sample database that the company is using for testing purposes. I (we) did not create the database — it was sent over to us by another company. I’m still a rank newbie at working with MS SQL Server, though I’ve worked with Access and MySQL in the past.

There is one table that contains bank information. At the moment, it is filled with information on imaginary (fake) banks. I need to change one record so that it contains the information of a real bank the company is using.

The problem is, I am unable to touch anything within this table. Any attempt to make changes gives me an error prompt that reads «String or binary data would be truncated». I ran the profiler, and it shows an Exception — Error: 8152 Severity 16 State 2.

Furthermore, I also get an error prompt stating: «The value you entered is not consistent with the data type or length of this column».

I’ve checked and checked again, and as far as I can tell, the value I entered _is_ consistent with the data type/length of the column.

I can make changes perfectly fine on the other tables in the database. Only this one table gives me trouble.

Could anyone shed some light on why exactly this is occurring, and why only on this one table?

Источник

Заметки системного администратора Windows Server

Поиск по этому блогу

Ошибка Microsoft SQL Server: SQL SERVER-Msg 8152, Уровень 16, состояние 14-строковые или двоичные данные будут усечены

  • Получить ссылку
  • Facebook
  • Twitter
  • Pinterest
  • Электронная почта
  • Другие приложения

Подробности ошибки:

Строковые или двоичные данные будут усечены. Заявление было прекращено.

This error message below occurs when part data is been truncated while loading a table.

Фактическое сообщение об ошибке:

Msg 8152, Level 16, State 14, Line 8
String or binary data would be truncated.
The statement has been terminated.

Решение:

Либо сократите данные, которые усекаются, либо увеличьте длину столбца в таблице, либо используйте инструкции below вверху и внизу инструкции sql insert, которая подавляет ошибку.

SET ANSI_WARNINGS OFF;
— Insert TSQL here.
SET ANSI_WARNINGS ON;

При использовании Andi_Warnings off ошибка будет подавлена в приведенном выше коде, но мы потеряли часть фактических данных, которые должны были быть у нас в таблице. Поэтому будьте осторожны при работе с такими заданными опциями.

Дополнительная информация ниже:

Используйте ANSI_WARNING OFF с осторожностью, так как иногда важные данные могут быть усечены или потеряны. Также оказывает негативное влияние на производительность оператора insert.

Источник

Sql server 8152 error

Вопрос

Здравствуйте, у меня на SCCM 2012 SP1 возникает следующая ошибка

*** [22001][8152][Microsoft][SQL Server Native Client 11.0][SQL Server]String or binary data would be truncated. : dINSTALLED_SOFTWARE_DATA

Как я понял? на SCCM сервер приходит отчет об инвентаризации програмного обеспечения, и сервер пытается эти данные записать в таблицу dINSTALLED_SOFTWARE_DATA на сиквел сервере. Но то ли в этом отчете есть длинные строчки, то ли целиком файл для sql большой, и сиквел не принимает данные от SCCM сервера

Я запустил на SQL сервере profiler, но он выдает ту же самую ошибку String or binary data would be truncated. Но что имено нужно обрезать, не говорит.

Можно ли узнать, что конкретно не нравится сиквелу во входящих данных?

Я в профайлере включил, в дополнение к стандартным данным, вывод всех ошибок.

Ответы

Для будущих поколений:

Проблема возникает при записи в таблицу INSTALLED_SOFTWARE_HIST, чье поле ServicePack00 имеет формат nvarchar(8), в то время в таблице, откуда копируются данные — INSTALLED_SOFTWARE_DATA — формат этого поля nvarchar(255).

Простое решение — это расширить проблемное поле до nvarchar(255), но без указки инженера Microsoft это переводит базу в состояние unsupported.

Проблема на самом деле заключается еще и в том, что в идеале в это поле никогда не должны писаться данные длиннее 1 символа. Если проверить содержимое этого поля после инвентаризации чистой машины, то там будет «1» в случае версии Service Pack 1. Однако в случае кастомных заливок в данных инвентаризации появляются 2 инстанса операционной системы, одна нормальная, вторая же содержит в этом поле «Service Pack 1» — 14 символов.

Источник появления второго инстанса ОС при инвентаризации WMI-класса Installed_Software пока неизвестен, скорее всего это какое-то расхождение в 32- и 64-хбитных ветках реестра HKLMSoftwareMicrosoftWindows NTCurrentVersion.

Правильное решение в этом случае: перезалить машину чистой проверенной заливкой или отключить инвентаризацию этого класса.

Тест машины на «кривость» — в консоли PS от имени администратора при установленном клиенте запустить: gwmi -namespace rootcimv2sms -query «select * from sms_installedsoftware
where Servicepack<>»»

Если выдается 1 инстанс — все хорошо, если два — машину стоит перезалить.

  • Предложено в качестве ответа Pavel Yurenev Microsoft employee 9 октября 2013 г. 14:49
  • Помечено в качестве ответа Иван Проданов Microsoft contingent staff, Moderator 10 октября 2013 г. 4:57

нужно включить в Profiler отображение SP: STMTStarting ещё.

так как SQL: StmtStarting показывает только выполнение хранимой процедуры (например, dbo.dInstalled_Software_Data или dbo.pInstalled_Software_Data), а процедура, как оказалось, пишет не в одну таблицу, а в несколько разных, и SP: STMTStarting, как раз, показывает, какая таблица не может принять данные (в моем случае, это оказалась совершенно левая таблица).

Правда, не удалось разобраться, как узнать, какое поле при этом нужно увеличивать. Пришлось увеличить все nvarchar. Благо полей оказалось не так много.

  • Помечено в качестве ответа Иван Проданов Microsoft contingent staff, Moderator 28 мая 2013 г. 14:15

Все ответы

Достаточно в профайлере добавить 2 события:

SQL: BatchStarting и Exception

Msg 8152, Level 16, State 14, Line 1 String or binary data would be truncated.

The statement has been terminated.

Вот этот SQL:BatchStarting содержит данные вида

exec dbo.dINSTALLED_SOFTWARE_DATA 4,16777259,’05/27/2013 10:05:27′,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,N’‘,NULL,N’Microsoft Visual C++ 2008 Redistributable — x86 9.0.30729.4148′,N’9.0.30729.4148′,NULL,NULL,NULL,N’<1f1c2dfc-2d24-3e06-bcb8-725134adf989>‘,NULL,NULL,N’MsiExec.exe /X<1f1c2dfc-2d24-3e06-bcb8-725134adf989>‘,NULL,NULL,NULL exec dbo.dINSTALLED_SOFTWARE_DATA 4,16777259,’05/27/2013 10:05:27′,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,N’‘,NULL,N’Microsoft Visual C++ 2010 x86 Redistributable — 10.0.30319′,N’10.0.30319′,NULL,NULL,NULL,N’<196bb40d-1578-3d01-b289-befc77a11a1e>‘,NULL,NULL,N’MsiExec.exe /X<196bb40d-1578-3d01-b289-befc77a11a1e>‘,NULL,NULL,NULL exec dbo.dINSTALLED_SOFTWARE_DATA 4,16777259,’05/27/2013 10:05:27′,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,N’<6b1a624c-dedd-4728-8f85-04f648ae1262>‘,N’1′,N’КОМПАС-3D V13′,N’13.0.2′,NULL,NULL,NULL,N’‘,NULL,NULL,N’MsiExec.exe /I‘,NULL,NULL,NULL

и таких данных несколько экранов. Просто я не совсем в курсе этой ошибки. Она значит, что значение в каком-то столбце превышает допустимую длину переменной, или это может значить, что стоит null, а null запрещен, или несовпадает формат даты времени, или вот эти несколько страниц данных нельзя запихивать в сиквел одновременно?

По поводу первого, скорее всего нет, так как я смотрел, самая большая строчка 180 символов, а переменная nvarchar(255).

По поводу остального, не знаю как проверить.

Да, в одной такой записи, после exec.dbo стоят и другие таблицы из той же базы. И exeption звучит имено так

String or binary data would be truncated.

А про номер ошибки я могу узнать только из логов SCCM. Вряд ли он сам знает, что это за ошибка. Скорее всего ему эти данные дает SQL. А вот где они записаны, не понятно. В тех логах которые я включил, про 8152 ничего нет.

После этого exeption идут другие, так как запись в эту таблицу (dINSTALLED_SOFTWARE_DATA) не произошла, начинают сыпаться ошибки про таблицу содержащую суммарные данные и т.д. (Там кстати ошибка вполне конкретная: Cannot insert the value NULL into column ‘RevisionID’, table ‘CM_OPT.dbo.INSTALLED_SOFTWARE_HIST’; column does not allow nulls. INSERT fails.) Но это из-за того, что не произошла вставка первоночальных данных.

но там 15 столбцов, какой именно столбец не подходит?

И как я понял нельзя руками менять длинну переменной?

но там 15 столбцов, какой именно столбец не подходит?

И как я понял нельзя руками менять длинну переменной?

1) какой столбец вам придётся определить самостоятельно, проанализировав входные данные и размерность полей таблицы

2) что вы имеете в виду?

1) данные я проанализировал, они меньше длинны переменной. Ну, насколько это возможно, там несколько мегабайт данных, может быть что-то и пропустил.

А нет ли возможности определить это автоматически?

2) я могу в таблице выделить любой столбец, нажать изменить и поменять тип переменной, нпример, вместо nvarchar(255) поставить nvarchar(511). Но где-то было написано, что так лучше не делать.

1) данные я проанализировал, они меньше длинны переменной. Ну, насколько это возможно, там несколько мегабайт данных, может быть что-то и пропустил.

А нет ли возможности определить это автоматически?

2) я могу в таблице выделить любой столбец, нажать изменить и поменять тип переменной, нпример, вместо nvarchar(255) поставить nvarchar(511). Но где-то было написано, что так лучше не делать.

ошибка, которую вы получаете связана с размером полей, а не переменных.

изменение размерности поля в таблице — это штатная ситуация

Ткните, пожалуйста, где можно почитать про изменение полей в таблице.

Если нажать кнопку изменить на столбце, то я вижу название столбца, его data type, и может быть он null или нет.

Data type для столбца я изменить не могу, так как в этом случае будет пересоздана вся таблица, а в её свойствах запрещено пересоздание.

Altering a Column Definition

  • A. Changing the data type of a column
  • B. Changing the size of a column

Спасибо, но не помогло. Ошибка осталась.

Да, действительно, ошибка осталась, но блоков данных стало приниматься больше. То есть SCCM передает данные блоками, и раньше сиквел падал на третьем блоке, а теперь на седьмом.

Но это как иголку в стоге сена 🙁 несколько сотен баз и половина полей в них не хочет увеличиваться.

Как я понял раньше (до 2012 версии) сиквел посылал конкретные сообщения в SCCM — вот этот столбец слишком узкий, а тот, в свою очередь, посылал сиквелу alter этот столбец. A теперь безликая ошибка и соответственно автоматически ситуацию не исправить.

Про set ansi_warnings

насколько я понял, это относится к INSERT и UPDATE. А в моем случае EXEC.

насколько я понял, это относится к INSERT и UPDATE. А в моем случае EXEC.

Сам по себе exec ничего не вставляет, вставка осуществляется через команду INSERT, поэтому вам достаточно в процедуру добавить эту настройку и все вставки пройдут без ошибок, НО(!) имейте в виду, что вы потеряете часть данных т.к. они усекутся под размер ваших полей.

И всё-таки не думаю, что так уж сложно найти в какое поле не могут быть записаны данные, профайлер в руки и несколько минут вашего времени должны помочь найти причину!

вот, я и не пойму как это сделать. Несколько сот классов инвентаризации. Можно по очереди включать их, потом дожидаться, когда на всех клиентах пройдет инвентаризация и проверять, что нет ошибок. В один блок данных попадает около трех таблиц, по 10-15 полей в каждой. это несколько недель, а не минут.

А если потом появится новый клиент со специфическим ПО или драйвером и нужно заново проверять все триста полей.

Что-то тут не так.

Спасибо, будем искать специалиста.

Но всё равно спасибо за помощь.

нужно включить в Profiler отображение SP: STMTStarting ещё.

так как SQL: StmtStarting показывает только выполнение хранимой процедуры (например, dbo.dInstalled_Software_Data или dbo.pInstalled_Software_Data), а процедура, как оказалось, пишет не в одну таблицу, а в несколько разных, и SP: STMTStarting, как раз, показывает, какая таблица не может принять данные (в моем случае, это оказалась совершенно левая таблица).

Правда, не удалось разобраться, как узнать, какое поле при этом нужно увеличивать. Пришлось увеличить все nvarchar. Благо полей оказалось не так много.

  • Помечено в качестве ответа Иван Проданов Microsoft contingent staff, Moderator 28 мая 2013 г. 14:15

Для будущих поколений:

Проблема возникает при записи в таблицу INSTALLED_SOFTWARE_HIST, чье поле ServicePack00 имеет формат nvarchar(8), в то время в таблице, откуда копируются данные — INSTALLED_SOFTWARE_DATA — формат этого поля nvarchar(255).

Простое решение — это расширить проблемное поле до nvarchar(255), но без указки инженера Microsoft это переводит базу в состояние unsupported.

Проблема на самом деле заключается еще и в том, что в идеале в это поле никогда не должны писаться данные длиннее 1 символа. Если проверить содержимое этого поля после инвентаризации чистой машины, то там будет «1» в случае версии Service Pack 1. Однако в случае кастомных заливок в данных инвентаризации появляются 2 инстанса операционной системы, одна нормальная, вторая же содержит в этом поле «Service Pack 1» — 14 символов.

Источник появления второго инстанса ОС при инвентаризации WMI-класса Installed_Software пока неизвестен, скорее всего это какое-то расхождение в 32- и 64-хбитных ветках реестра HKLMSoftwareMicrosoftWindows NTCurrentVersion.

Правильное решение в этом случае: перезалить машину чистой проверенной заливкой или отключить инвентаризацию этого класса.

Тест машины на «кривость» — в консоли PS от имени администратора при установленном клиенте запустить: gwmi -namespace rootcimv2sms -query «select * from sms_installedsoftware
where Servicepack<>»»

Если выдается 1 инстанс — все хорошо, если два — машину стоит перезалить.

  • Предложено в качестве ответа Pavel Yurenev Microsoft employee 9 октября 2013 г. 14:49
  • Помечено в качестве ответа Иван Проданов Microsoft contingent staff, Moderator 10 октября 2013 г. 4:57

Неужели я такой счастливчик, что единственный словил этот баг.

А не подскажете как зарегистрировать можно?

А не подскажете как зарегистрировать можно?

В R2 точно не поправлено, т.к. не зарегистрировано как баг. Sad but true.

Большое спасибо, у меня руки так и не дошли зарегистрировать баг.

Правильное решение в этом случае: перезалить машину чистой проверенной заливкой или отключить инвентаризацию этого класса.

Попробовал на паре(20) машин, данные обновились:

1. Делаем коллекцию из старых машин(старые данные HardwareInventory):

select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_WORKSTATION_STATUS on SMS_G_System_WORKSTATION_STATUS.ResourceId = SMS_R_System.ResourceId where SMS_G_System_WORKSTATION_STATUS.LastHardwareScan

Если есть контракт премьер-поддержки, то Вы можете попросту попросить разрешение у меня, открыв заявку. В свою очередь я Вам буду настоятельно рекомендовать перезалить машины проверенным образом, как я писал выше.

Если честно, если Вы поменяете базу самостоятельно, с вероятностью 95% проблем не будет, а инженер поддержки этого попросту не заметит, если Вы сами ему не расскажете. 🙂

P.S. Фикс отложили на следующий релиз SCCM, который выйдет в 2015 году.

Столкнулся с такой же проблемой на SCCM 2012 R2 5.00.7958.1000.
Машины залиты проверенным, созданным и залитым через SCCM образом ОС Windows 7.
Проблема возникла словно сама собой месяца три назад, т.к. классы инвентаризации не менялись.
Сейчас проблемных машин — 80%.

1. Как мне получить это одобрение на модификацию БД (куплен EAS)?
2. Где можно увидеть в каком состоянии БД «unsupported» или «supported»?
3. Если она перейдет с состояние «unsupported» (после изменения длинны поля) — чем это чревато?
4. Где можно найти официальное описание/статус зарегистрированного бага SCCM 2012 R2 «bug (SMS 410599)» — «SMS_INVENTORY_DATA_LOADER Microsoft SQL Server 8152 SQL issued a message, the importance of 16: [22001] [8152] [Microsoft] [SQL Server Native Client 11.0] [SQL Server] String or binary data would be truncated. : pINSTALLED_SOFTWARE_DATA«?

Проблема возникает при записи в таблицу INSTALLED_SOFTWARE_HIST, чье поле ServicePack00 имеет формат nvarchar(8), в то время в таблице, откуда копируются данные — INSTALLED_SOFTWARE_DATA — формат этого поля nvarchar(255).

Простое решение — это расширить проблемное поле до nvarchar(255), но без указки инженера Microsoft это переводит базу в состояние unsupported.

Проблема на самом деле заключается еще и в том, что в идеале в это поле никогда не должны писаться данные длиннее 1 символа. Если проверить содержимое этого поля после инвентаризации чистой машины, то там будет «1» в случае версии Service Pack 1. Однако в случае кастомных заливок в данных инвентаризации появляются 2 инстанса операционной системы, одна нормальная, вторая же содержит в этом поле «Service Pack 1» — 14 символов.

Источник появления второго инстанса ОС при инвентаризации WMI-класса Installed_Software пока неизвестен, скорее всего это какое-то расхождение в 32- и 64-хбитных ветках реестра HKLMSoftwareMicrosoftWindows NTCurrentVersion.

Правильное решение в этом случае: перезалить машину чистой проверенной заливкой или отключить инвентаризацию этого класса.

Тест машины на «кривость» — в консоли PS от имени администратора при установленном клиенте запустить: gwmi -namespace rootcimv2sms -query «select * from sms_installedsoftware
where Servicepack<>»»

Если выдается 1 инстанс — все хорошо, если два — машину стоит перезалить.

А какой тут у меня инстанс на скриншоте, Подскажите.

Источник

I have created a simple way of finding offending fields by:

  1. Getting the column width of all the columns of a table where we’re trying to make this insert/ update. (I’m getting this info directly from the database.)
  2. Comparing the column widths to the width of the values we’re trying to insert/ update.

Assumptions/ Limitations:

  1. The column names of the table in the database match with the C# entity fields. For eg: If you have a column like this in database:

    You need to have your Entity with the same column name:

    public class SomeTable
    {
       // Other fields
       public string SourceData { get; set; }
    }
    
  2. You’re inserting/ updating 1 entity at a time. It’ll be clearer in the demo code below. (If you’re doing bulk inserts/ updates, you might want to either modify it or use some other solution.)

Step 1:

Get the column width of all the columns directly from the database:

// For this, I took help from Microsoft docs website:
// https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlconnection.getschema?view=netframework-4.7.2#System_Data_SqlClient_SqlConnection_GetSchema_System_String_System_String___
private static Dictionary<string, int> GetColumnSizesOfTableFromDatabase(string tableName, string connectionString)
{
    var columnSizes = new Dictionary<string, int>();
            
    using (var connection = new SqlConnection(connectionString))
    {
        // Connect to the database then retrieve the schema information.  
        connection.Open();

        // You can specify the Catalog, Schema, Table Name, Column Name to get the specified column(s).
        // You can use four restrictions for Column, so you should create a 4 members array.
        String[] columnRestrictions = new String[4];

        // For the array, 0-member represents Catalog; 1-member represents Schema;
        // 2-member represents Table Name; 3-member represents Column Name.
        // Now we specify the Table_Name and Column_Name of the columns what we want to get schema information.
        columnRestrictions[2] = tableName;

        DataTable allColumnsSchemaTable = connection.GetSchema("Columns", columnRestrictions);

        foreach (DataRow row in allColumnsSchemaTable.Rows)
        {
            var columnName = row.Field<string>("COLUMN_NAME");
            //var dataType = row.Field<string>("DATA_TYPE");
            var characterMaxLength = row.Field<int?>("CHARACTER_MAXIMUM_LENGTH");

            // I'm only capturing columns whose Datatype is "varchar" or "char", i.e. their CHARACTER_MAXIMUM_LENGTH won't be null.
            if(characterMaxLength != null)
            {
                columnSizes.Add(columnName, characterMaxLength.Value);
            }
        }

        connection.Close();
    }

    return columnSizes;
}

Step 2:

Compare the column widths with the width of the values we’re trying to insert/ update:

public static Dictionary<string, string> FindLongBinaryOrStringFields<T>(T entity, string connectionString)
{
    var tableName = typeof(T).Name;
    Dictionary<string, string> longFields = new Dictionary<string, string>();
    var objectProperties = GetProperties(entity);
    //var fieldNames = objectProperties.Select(p => p.Name).ToList();

    var actualDatabaseColumnSizes = GetColumnSizesOfTableFromDatabase(tableName, connectionString);
            
    foreach (var dbColumn in actualDatabaseColumnSizes)
    {
        var maxLengthOfThisColumn = dbColumn.Value;
        var currentValueOfThisField = objectProperties.Where(f => f.Name == dbColumn.Key).First()?.GetValue(entity, null)?.ToString();

        if (!string.IsNullOrEmpty(currentValueOfThisField) && currentValueOfThisField.Length > maxLengthOfThisColumn)
        {
            longFields.Add(dbColumn.Key, $"'{dbColumn.Key}' column cannot take the value of '{currentValueOfThisField}' because the max length it can take is {maxLengthOfThisColumn}.");
        }
    }

    return longFields;
}

public static List<PropertyInfo> GetProperties<T>(T entity)
{
    //The DeclaredOnly flag makes sure you only get properties of the object, not from the classes it derives from.
    var properties = entity.GetType()
                            .GetProperties(System.Reflection.BindingFlags.Public
                            | System.Reflection.BindingFlags.Instance
                            | System.Reflection.BindingFlags.DeclaredOnly)
                            .ToList();

    return properties;
}

Demo:

Let’s say we’re trying to insert someTableEntity of SomeTable class that is modeled in our app like so:

public class SomeTable
{
    [Key]
    public long TicketID { get; set; }
    public string SourceData { get; set; }
}

And it’s inside our SomeDbContext like so:

public class SomeDbContext : DbContext
{
    public DbSet<SomeTable> SomeTables { get; set; }
}

This table in Db has SourceData field as varchar(16) like so:

Now we’ll try to insert value that is longer than 16 characters into this field and capture this information:

public void SaveSomeTableEntity()
{
    var connectionString = "server=SERVER_NAME;database=DB_NAME;User ID=SOME_ID;Password=SOME_PASSWORD;Connection Timeout=200";
        
    using (var context = new SomeDbContext(connectionString))
    {
        var someTableEntity = new SomeTable()
        {
            SourceData = "Blah-Blah-Blah-Blah-Blah-Blah"
        };
        
        context.SomeTables.Add(someTableEntity);
        
        try
        {
            context.SaveChanges();
        }
        catch (Exception ex)
        {
            if (ex.GetBaseException().Message == "String or binary data would be truncated.rnThe statement has been terminated.")
            {
                var badFieldsReport = "";
                List<string> badFields = new List<string>();
                
                // YOU GOT YOUR FIELDS RIGHT HERE:
                var longFields = FindLongBinaryOrStringFields(someTableEntity, connectionString);

                foreach (var longField in longFields)
                {
                    badFields.Add(longField.Key);
                    badFieldsReport += longField.Value + "n";
                }
            }
            else
                throw;
        }
    }
}

The badFieldsReport will have this value:

‘SourceData’ column cannot take the value of
‘Blah-Blah-Blah-Blah-Blah-Blah’ because the max length it can take is
16.

If someone is encountering this error in a C# application, I have created a simple way of finding offending fields by:

  1. Getting the column width of all the columns of a table where we’re trying to make this insert/ update. (I’m getting this info directly from the database.)
  2. Comparing the column widths to the width of the values we’re trying to insert/ update.

Assumptions/ Limitations:

  1. The column names of the table in the database match with the C# entity fields. For eg: If you have a column like this in database:

    You need to have your Entity with the same column name:

    public class SomeTable
    {
       // Other fields
       public string SourceData { get; set; }
    }
    
  2. You’re inserting/ updating 1 entity at a time. It’ll be clearer in the demo code below. (If you’re doing bulk inserts/ updates, you might want to either modify it or use some other solution.)

Step 1:

Get the column width of all the columns directly from the database:

// For this, I took help from Microsoft docs website:
// https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlconnection.getschema?view=netframework-4.7.2#System_Data_SqlClient_SqlConnection_GetSchema_System_String_System_String___
private static Dictionary<string, int> GetColumnSizesOfTableFromDatabase(string tableName, string connectionString)
{
    var columnSizes = new Dictionary<string, int>();
            
    using (var connection = new SqlConnection(connectionString))
    {
        // Connect to the database then retrieve the schema information.  
        connection.Open();

        // You can specify the Catalog, Schema, Table Name, Column Name to get the specified column(s).
        // You can use four restrictions for Column, so you should create a 4 members array.
        String[] columnRestrictions = new String[4];

        // For the array, 0-member represents Catalog; 1-member represents Schema;
        // 2-member represents Table Name; 3-member represents Column Name.
        // Now we specify the Table_Name and Column_Name of the columns what we want to get schema information.
        columnRestrictions[2] = tableName;

        DataTable allColumnsSchemaTable = connection.GetSchema("Columns", columnRestrictions);

        foreach (DataRow row in allColumnsSchemaTable.Rows)
        {
            var columnName = row.Field<string>("COLUMN_NAME");
            //var dataType = row.Field<string>("DATA_TYPE");
            var characterMaxLength = row.Field<int?>("CHARACTER_MAXIMUM_LENGTH");

            // I'm only capturing columns whose Datatype is "varchar" or "char", i.e. their CHARACTER_MAXIMUM_LENGTH won't be null.
            if(characterMaxLength != null)
            {
                columnSizes.Add(columnName, characterMaxLength.Value);
            }
        }

        connection.Close();
    }

    return columnSizes;
}

Step 2:

Compare the column widths with the width of the values we’re trying to insert/ update:

public static Dictionary<string, string> FindLongBinaryOrStringFields<T>(T entity, string connectionString)
{
    var tableName = typeof(T).Name;
    Dictionary<string, string> longFields = new Dictionary<string, string>();
    var objectProperties = GetProperties(entity);
    //var fieldNames = objectProperties.Select(p => p.Name).ToList();

    var actualDatabaseColumnSizes = GetColumnSizesOfTableFromDatabase(tableName, connectionString);
            
    foreach (var dbColumn in actualDatabaseColumnSizes)
    {
        var maxLengthOfThisColumn = dbColumn.Value;
        var currentValueOfThisField = objectProperties.Where(f => f.Name == dbColumn.Key).First()?.GetValue(entity, null)?.ToString();

        if (!string.IsNullOrEmpty(currentValueOfThisField) && currentValueOfThisField.Length > maxLengthOfThisColumn)
        {
            longFields.Add(dbColumn.Key, $"'{dbColumn.Key}' column cannot take the value of '{currentValueOfThisField}' because the max length it can take is {maxLengthOfThisColumn}.");
        }
    }

    return longFields;
}

public static List<PropertyInfo> GetProperties<T>(T entity)
{
    //The DeclaredOnly flag makes sure you only get properties of the object, not from the classes it derives from.
    var properties = entity.GetType()
                            .GetProperties(System.Reflection.BindingFlags.Public
                            | System.Reflection.BindingFlags.Instance
                            | System.Reflection.BindingFlags.DeclaredOnly)
                            .ToList();

    return properties;
}

Demo:

Let’s say we’re trying to insert someTableEntity of SomeTable class that is modeled in our app like so:

public class SomeTable
{
    [Key]
    public long TicketID { get; set; }
    public string SourceData { get; set; }
}

And it’s inside our SomeDbContext like so:

public class SomeDbContext : DbContext
{
    public DbSet<SomeTable> SomeTables { get; set; }
}

This table in Db has SourceData field as varchar(16) like so:

Now we’ll try to insert value that is longer than 16 characters into this field and capture this information:

public void SaveSomeTableEntity()
{
    var connectionString = "server=SERVER_NAME;database=DB_NAME;User ID=SOME_ID;Password=SOME_PASSWORD;Connection Timeout=200";
        
    using (var context = new SomeDbContext(connectionString))
    {
        var someTableEntity = new SomeTable()
        {
            SourceData = "Blah-Blah-Blah-Blah-Blah-Blah"
        };
        
        context.SomeTables.Add(someTableEntity);
        
        try
        {
            context.SaveChanges();
        }
        catch (Exception ex)
        {
            if (ex.GetBaseException().Message == "String or binary data would be truncated.rnThe statement has been terminated.")
            {
                var badFieldsReport = "";
                List<string> badFields = new List<string>();
                
                // YOU GOT YOUR FIELDS RIGHT HERE:
                var longFields = FindLongBinaryOrStringFields(someTableEntity, connectionString);

                foreach (var longField in longFields)
                {
                    badFields.Add(longField.Key);
                    badFieldsReport += longField.Value + "n";
                }
            }
            else
                throw;
        }
    }
}

The badFieldsReport will have this value:

‘SourceData’ column cannot take the value of
‘Blah-Blah-Blah-Blah-Blah-Blah’ because the max length it can take is
16.

If someone is encountering this error in a C# application, I have created a simple way of finding offending fields by:

  1. Getting the column width of all the columns of a table where we’re trying to make this insert/ update. (I’m getting this info directly from the database.)
  2. Comparing the column widths to the width of the values we’re trying to insert/ update.

Assumptions/ Limitations:

  1. The column names of the table in the database match with the C# entity fields. For eg: If you have a column like this in database:

    You need to have your Entity with the same column name:

    public class SomeTable
    {
       // Other fields
       public string SourceData { get; set; }
    }
    
  2. You’re inserting/ updating 1 entity at a time. It’ll be clearer in the demo code below. (If you’re doing bulk inserts/ updates, you might want to either modify it or use some other solution.)

Step 1:

Get the column width of all the columns directly from the database:

// For this, I took help from Microsoft docs website:
// https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlconnection.getschema?view=netframework-4.7.2#System_Data_SqlClient_SqlConnection_GetSchema_System_String_System_String___
private static Dictionary<string, int> GetColumnSizesOfTableFromDatabase(string tableName, string connectionString)
{
    var columnSizes = new Dictionary<string, int>();
            
    using (var connection = new SqlConnection(connectionString))
    {
        // Connect to the database then retrieve the schema information.  
        connection.Open();

        // You can specify the Catalog, Schema, Table Name, Column Name to get the specified column(s).
        // You can use four restrictions for Column, so you should create a 4 members array.
        String[] columnRestrictions = new String[4];

        // For the array, 0-member represents Catalog; 1-member represents Schema;
        // 2-member represents Table Name; 3-member represents Column Name.
        // Now we specify the Table_Name and Column_Name of the columns what we want to get schema information.
        columnRestrictions[2] = tableName;

        DataTable allColumnsSchemaTable = connection.GetSchema("Columns", columnRestrictions);

        foreach (DataRow row in allColumnsSchemaTable.Rows)
        {
            var columnName = row.Field<string>("COLUMN_NAME");
            //var dataType = row.Field<string>("DATA_TYPE");
            var characterMaxLength = row.Field<int?>("CHARACTER_MAXIMUM_LENGTH");

            // I'm only capturing columns whose Datatype is "varchar" or "char", i.e. their CHARACTER_MAXIMUM_LENGTH won't be null.
            if(characterMaxLength != null)
            {
                columnSizes.Add(columnName, characterMaxLength.Value);
            }
        }

        connection.Close();
    }

    return columnSizes;
}

Step 2:

Compare the column widths with the width of the values we’re trying to insert/ update:

public static Dictionary<string, string> FindLongBinaryOrStringFields<T>(T entity, string connectionString)
{
    var tableName = typeof(T).Name;
    Dictionary<string, string> longFields = new Dictionary<string, string>();
    var objectProperties = GetProperties(entity);
    //var fieldNames = objectProperties.Select(p => p.Name).ToList();

    var actualDatabaseColumnSizes = GetColumnSizesOfTableFromDatabase(tableName, connectionString);
            
    foreach (var dbColumn in actualDatabaseColumnSizes)
    {
        var maxLengthOfThisColumn = dbColumn.Value;
        var currentValueOfThisField = objectProperties.Where(f => f.Name == dbColumn.Key).First()?.GetValue(entity, null)?.ToString();

        if (!string.IsNullOrEmpty(currentValueOfThisField) && currentValueOfThisField.Length > maxLengthOfThisColumn)
        {
            longFields.Add(dbColumn.Key, $"'{dbColumn.Key}' column cannot take the value of '{currentValueOfThisField}' because the max length it can take is {maxLengthOfThisColumn}.");
        }
    }

    return longFields;
}

public static List<PropertyInfo> GetProperties<T>(T entity)
{
    //The DeclaredOnly flag makes sure you only get properties of the object, not from the classes it derives from.
    var properties = entity.GetType()
                            .GetProperties(System.Reflection.BindingFlags.Public
                            | System.Reflection.BindingFlags.Instance
                            | System.Reflection.BindingFlags.DeclaredOnly)
                            .ToList();

    return properties;
}

Demo:

Let’s say we’re trying to insert someTableEntity of SomeTable class that is modeled in our app like so:

public class SomeTable
{
    [Key]
    public long TicketID { get; set; }
    public string SourceData { get; set; }
}

And it’s inside our SomeDbContext like so:

public class SomeDbContext : DbContext
{
    public DbSet<SomeTable> SomeTables { get; set; }
}

This table in Db has SourceData field as varchar(16) like so:

Now we’ll try to insert value that is longer than 16 characters into this field and capture this information:

public void SaveSomeTableEntity()
{
    var connectionString = "server=SERVER_NAME;database=DB_NAME;User ID=SOME_ID;Password=SOME_PASSWORD;Connection Timeout=200";
        
    using (var context = new SomeDbContext(connectionString))
    {
        var someTableEntity = new SomeTable()
        {
            SourceData = "Blah-Blah-Blah-Blah-Blah-Blah"
        };
        
        context.SomeTables.Add(someTableEntity);
        
        try
        {
            context.SaveChanges();
        }
        catch (Exception ex)
        {
            if (ex.GetBaseException().Message == "String or binary data would be truncated.rnThe statement has been terminated.")
            {
                var badFieldsReport = "";
                List<string> badFields = new List<string>();
                
                // YOU GOT YOUR FIELDS RIGHT HERE:
                var longFields = FindLongBinaryOrStringFields(someTableEntity, connectionString);

                foreach (var longField in longFields)
                {
                    badFields.Add(longField.Key);
                    badFieldsReport += longField.Value + "n";
                }
            }
            else
                throw;
        }
    }
}

The badFieldsReport will have this value:

‘SourceData’ column cannot take the value of
‘Blah-Blah-Blah-Blah-Blah-Blah’ because the max length it can take is
16.

Я
   Ёхан Палыч

05.06.17 — 10:50

В какую сторону думать даже не знаю.

Выдает при печати ЗКР и вылетает из программы (Конф. БГУ 1.0):

Ошибка СУБД:

Microsoft SQL Native Client 10.0: Символьные или двоичные данные могут быть усечены. HRESULT=80040E57, SQLSrvr: SQLSTATE=22001, state=D, Severity=10? native=8152? line=1

ТИИ не помогает

   Heckfy

1 — 05.06.17 — 10:53

http://www.psub.net/Publication/Details/51

http://www.sql.ru/forum/490123/simvolnye-ili-dvoichnye-dannye-mogut-byt-usecheny

https://yandex.ru/search/?lr=213&msid=1496649117.355.22900.31980&text=1С%20Символьные%20или%20двоичные%20данные%20могут%20быть%20усечены

   Sammo

2 — 05.06.17 — 10:54

Ошибка: Символьные или двоичные данные могут быть усечены (String or binary data would be truncated)

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

Пример:

В таблицы БД поле имеет тип varchar(20), а размер строки, записываемый в него, превышает 20 символов

   Ёхан Палыч

3 — 05.06.17 — 11:10

спасибо, гляну

   Ёхан Палыч

4 — 15.06.17 — 06:57

что сделать то в контексте 1с, не охото лезть в СКЛ, да и не знаю я там куда лезть то.

может кто подскажет????

   mehfk

5 — 15.06.17 — 07:37

Отладчик в помощь.

   Провинциальный 1сник

6 — 15.06.17 — 08:12

(0) «ТИИ не помогает»

А выгрузка-загрузка?

(5) Вряд ли тут поможет отладчик. Скорее, проблема с внутренней структурой базы. При каком-то обновлении метаданных не произошло синхронного изменения структуры таблиц в БД.

   Ёхан Палыч

7 — 15.06.17 — 08:24

тии и загрузка-выгрузка не помогает.

может обновление накатить?

   Провинциальный 1сник

8 — 15.06.17 — 08:39

(7)А загрузка в файловую базу? Там тоже ошибка или нет?

   Ёхан Палыч

9 — 15.06.17 — 08:53

(8) надо попробовать, а если нет, то что это решит?

   Провинциальный 1сник

10 — 15.06.17 — 08:57

(9) Ну тогда попробовать после выгрузки из файловой базы загрузить на какую-то другую субд. Постгрес или sql другой версии.

   don_Rumata

11 — 15.06.17 — 08:57

(9) Можно будет перейти на нормальный постгре с поделки (0)

   mehfk

12 — 15.06.17 — 09:00

(6) >>  Вряд ли тут поможет отладчик.

Да ты гонишь!

  

Ёхан Палыч

13 — 15.06.17 — 09:20

спасибо, все попробую

начал читать тему и понял, что как всегда — вместо того, чтобы поддержать или научить, человеку рассказывают о том, как отмазаться или не делать mikecool

ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку «Обновить» в браузере.

Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.

SQL Server 2012 Enterprise SQL Server 2012 Developer SQL Server 2012 Standard SQL Server 2014 Developer SQL Server 2014 Enterprise SQL Server 2014 Standard Еще…Меньше

Проблемы

Предположим, что у вас есть таблица, участвующая в одноранговой репликации Microsoft SQL Server 2012 или SQL Server 2014, а таблица содержит большое количество столбцов. При возникновении конфликта в этой таблице агент распространителя может завершиться ошибкой, и появляется следующее сообщение об ошибке:

Строковые или двоичные данные должны быть усечены. (Источник: MSSQLServer; номер ошибки: 8152)

Решение

Эта проблема впервые устранена в следующем накопительном обновлении SQL Server:

  • Накопительное обновление 3 для SQL Server 2014 с пакетом обновления 1 (SP1)

  • Накопительное обновление 10 для SQL Server 2014

  • Накопительное обновление 8 для SQL Server 2012 с пакетом обновления 2 (SP2)

Статус

Корпорация Майкрософт подтверждает наличие этой проблемы в своих продуктах, которые перечислены в разделе «Применяется к».

Нужна дополнительная помощь?

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Ms sql ошибка 18465
  • Ms sql server проверка базы на ошибки