Есть ли хороший способ отладки "Строка или двоичные данные будут обрезаны?" - PullRequest
24 голосов
/ 14 июля 2010

Год - 2010.

Лицензии на SQL Server недешевы.

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

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

Ответы [ 10 ]

17 голосов
/ 14 июля 2010

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

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

..., а затем сравнить схему этой таблицы со схемойтаблица, в которую ранее вставлялась вставка - и ищите столбцы большего размера.

2 голосов
/ 15 декабря 2016

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

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

2 голосов
/ 07 февраля 2016

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

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

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;
1 голос
/ 26 июня 2017

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

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_' и отображает максимальную длину каждого столбца.

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

1 голос
/ 31 июля 2014

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

1 голос
/ 14 июля 2010

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

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

0 голосов
/ 22 сентября 2017

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

0 голосов
/ 14 июля 2010

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

a) Ваше определение столбца неверно, и ширина должна быть изменена б) Ваше определение столбца правильно, и приложение должно быть большеоборонительный

?

0 голосов
/ 14 июля 2010

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

0 голосов
/ 14 июля 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...