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

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

Год 2010 года.

Лицензии SQL Server не являются дешевыми.

И все же эта ошибка по-прежнему не указывает строку row или или , которая вызвала проблему. Черт, он даже не может сказать вам, были ли это "строковые" или "двоичные" данные.

Я что-то пропустил?

4b9b3361

Ответ 1

Быстрый и грязный способ их исправления состоит в том, чтобы выбрать строки в новую физическую таблицу следующим образом:

SELECT * INTO dbo.MyNewTable FROM <the rest of the offending query goes here>

... и затем сравните схему этой таблицы с схемой таблицы, в которую ранее был INSERT, и найдите более крупные столбцы.

Ответ 2

Я понимаю, что это старый. Здесь помогает небольшой фрагмент кода, который я использую.

Что это значит, возвращает таблицу максимальных длин в таблице, которую вы пытаетесь выбрать. Затем вы можете сравнить длины полей с max, возвращаемыми для каждого столбца, и выяснить, какие из них вызывают проблему. Затем это просто простой запрос для очистки данных или исключения из него.

DECLARE @col NVARCHAR(50)
DECLARE @sql NVARCHAR(MAX);

CREATE TABLE ##temp (colname nvarchar(50), maxVal int)

DECLARE oloop CURSOR FOR

SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'SOURCETABLENAME' AND TABLE_SCHEMA='dbo'

OPEN oLoop 

   FETCH NEXT FROM oloop INTO @col;

   WHILE (@@FETCH_STATUS = 0)
   BEGIN
      SET @sql = '
   DECLARE @val INT;
   SELECT @val = MAX(LEN(' + @col + ')) FROM dbo.SOURCETABLENAME;
   INSERT INTO ##temp
           ( colname, maxVal )
   VALUES  ( N''' + @col + ''', -- colname - nvarchar(50)
             @val  -- maxVal - int
             )';
      EXEC(@sql);
      FETCH NEXT FROM oloop INTO @col;
   END

   CLOSE oloop;
   DEALLOCATE oloop

   SELECT * FROM ##temp
   DROP TABLE ##temp;

Ответ 3

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

Это должно работать, если вам просто нужно определить, что является полем, вызывающим проблему. Я не знаю, есть ли лучший способ сделать это, хотя.

Ответ 4

Рекомендовать вас голосовать за запрос на улучшение на сайте Microsoft. Он был активным уже 6 лет, поэтому, кто знает, если Microsoft когда-нибудь что-нибудь с этим поделает, но по крайней мере вы можете быть скрипучим колесом: Microsoft Connect

Ответ 5

Другой способ здесь - использовать двоичный поиск.

Прокомментируйте половину столбцов в коде и повторите попытку. Если ошибка повторяется, прокомментируйте другую половину этой половины и повторите попытку. В конце вы сократите свой поиск до двух столбцов.

Ответ 6

Для усечения строк я придумал следующее решение, чтобы найти максимальные длины всех столбцов:

1) Выберите все данные во временную таблицу (при необходимости укажите имена столбцов поставок), например

SELECT  col1
       ,col2
       ,col3_4 = col3 + '-' + col4
INTO   #temp;

2) Запустите следующий оператор SQL в том же соединении (при необходимости измените имя временной таблицы):

DECLARE @table  VARCHAR(MAX) = '#temp';      -- change this to your temp table name

DECLARE @select VARCHAR(MAX) = '';
DECLARE @prefix VARCHAR(256) = 'MAX(LEN(';
DECLARE @suffix VARCHAR(256) = ')) AS max_';
DECLARE @nl     CHAR(2)      = CHAR(13) + CHAR(10);

SELECT  @select = @select + @prefix + name + @suffix + name + @nl + ','
FROM    tempdb.sys.columns 
WHERE   object_id = object_id('tempdb..' + @table);

SELECT  @select = 'SELECT ' + @select + '0' + @nl + 'FROM ' + @table

EXEC(@select);

Он вернет результирующий набор с именами столбцов с префиксом "max_" и покажет максимальную длину каждого столбца.

Как только вы идентифицируете неисправный столбец, вы можете запускать другие команды выбора, чтобы находить дополнительные длинные строки и при необходимости корректировать свой код/​​данные.

Ответ 7

Я не могу придумать хороший способ. Я как-то потратил много времени на отладку очень информативного сообщения "Деление на ноль".

Обычно вы комментируете различные фрагменты кода вывода, чтобы найти проблему, вызывающую проблемы.
Затем вы берете эту часть, которую вы нашли, и возвращаете значение, указывающее на наличие проблемы вместо фактического значения (в вашем случае следует заменить вывод строки на len(of the output)). Затем вручную сравните с длиной столбца, в который вы его вставляете.

Ответ 8

из номера строки в сообщении об ошибке, вы должны иметь возможность идентифицировать запрос вставки, вызывающий ошибку. измените это на запрос выбора, чтобы включить AND LEN(your_expression_or_column_here) > CONSTANT_COL_INT_LEN для строки различных столбцов в вашем запросе. посмотрите на результат, и он даст ваши плохие строки.

Ответ 9

Технически, нет строки, указывающей на то, что SQL не записывал данные в таблицу. Обычно я просто фиксирую трассировку, запускаю ее Query Analyzer (если проблема уже не очевидна из трассировки, которая может быть в этом случае) и быстро отлаживается оттуда с возрастом "измените мой метод UPDATE на SELECT". Разве это не просто разрушает одну из двух вещей:

a) Определение столбца неверно, и необходимо изменить ширину b) Правильное определение столбца, и приложение должно быть более защищенным.

?

Ответ 10

Самое лучшее, что сработало для меня, - это перенести строки во временную таблицу, используя select.... в #temptable Затем я взял максимальную длину каждого столбца в этой временной таблице. например. выберите max (len (jobid)) как Jobid,.... а затем сравнили это с определением поля исходной таблицы.