2009-07-07 2 views
5

SQL Server 2005 Вопрос:SQL Server: Узнайте, какие строки вызвали TSQL сбой (SSIS)

Я работаю над проектом преобразования данных, где я беру 80k + строк и перемещение их из одной таблицы другой. Когда я запускаю TSQL, он бомбит различные ошибки, связанные с преобразованиями типов или что-то еще. Есть ли способ узнать, какая строка вызвала ошибку?

=====================

UPDATE:

Я выполнении INSERT INTO table1 (...) SELECT. .. FROM TABLE2 Таблица 2 представляет собой всего лишь кучу полей varchar, где TABLE1 имеет правильные типы.

Этот скрипт будет помещен в sproc и выполнен из пакета SSIS. Сначала пакет SSIS импортирует 5 больших плоских файлов в таблицу 2.

Вот пример сообщения об ошибке: «Преобразование типа данных символа в тип данных даты и времени приводило к значению дат-времени вне диапазона».

Есть много полей даты. В таблице 2 имеются значения данных, такие как '02/05/1075 'для даты рождения. Я хочу изучить каждую строку, которая вызывает ошибку, поэтому я могу сообщить отделу, ответственному за плохие данные, чтобы они могли его исправить.

+0

Не могли бы вы привести несколько примеров ошибок? Как вы перемещаете данные с помощью инструкции вставки или курсоров? Насколько я знаю, на самом деле нет файла журнала, который точно скажет вам, что такое ошибка, но, возможно, с некоторыми сообщениями об ошибках мы можем указать вам в правильном направлении. – OhioDude

+0

Пожалуйста, обратите больше внимания на выбор тегов. –

+1

Если это вопрос кастинга, существуют функции ISNUMERIC и ISDATE, чтобы помочь проверить, может ли строка успешно использовать приведение в число или дату соответственно. ISNUMERIC хотя и имеет в себе недостаток в отношении запятых и пробелов, по моему опыту. Но да, ваш ОП должен быть более конкретным в отношении того, с какими ошибками вы сталкиваетесь. –

ответ

3

Что я расщепляется набор строк пополам с ИНЕКЕ:

INSERT MyTable(id, datecol) SELECT id, datecol FROM OtherTable WHERE ID BETWEEN 0 AND 40,000 

, а затем сохранить изменения значений на части между ИНЕКЕ. Я делал это вручную много раз, но мне приходит в голову, что вы можете автоматизировать расщепление с небольшим кодом .Net в цикле, исключая исключения захвата, а затем сужая его до строки, бросающей исключение, понемногу.

+4

Неправильный синтаксис и плохая идея для решения проблемы. Он будет работать (после исправления ошибки синтаксиса), но он наименее эффективен и действительно должен выполняться вручную, а не работать в пакете. Плохие даты легко идентифицируются с помощью функции isdate(). – HLGEM

+0

Исправлен плохой SQL. –

0

Если вы работаете с курсорами, да и тривиально. Если вы не работаете с курсорами, я так не думаю, потому что операции SQL - это ACID или транзакции как таковые.

2

Я предполагаю, что вы делаете обновление с INSERT INTO ...

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

+2

Согласитесь, строки 80k не так уж и много, поэтому курсор туда попадет; если есть более одной ошибки, это поможет. Не забывайте, что вы можете попробовать/поймать в sql 2005, чтобы вы могли хранить строки, которые не выполнялись и выполнялись с теми, которые работали. – u07ch

+1

Хорошая точка, u07ch: вставьте все, что не выбрасывало ошибку, тогда вы можете просто ВЛЕВО ПРИСОЕДИНЯЙТЕСЬ ... ГДЕ RIGHT.X IS NULL, чтобы проверить те, которые не были вставлены в один оператор. Если есть много строк, которые сбой, это будет лучшим решением, а не исправлением 1K ошибочных строк из 80K. Но, скорее всего, достаточно найти 1-2 разных причины, остальные должны быть одинаковыми, и их легко исправить. – van

1

Если вы зацикливаете, добавьте отпечатки в петлю.

Если вы используете операции на основе набора, добавьте ограничительное условие WHERE и запустите его. Продолжайте работать (каждый раз, делая его более строгим), пока не найдете строку в данных. если вы можете запустить его для блоков из N строк, просто выберите эти строки и посмотрите на них.

заявление ADD СЛУЧАЙ поймать проблемы (преобразование, что плохое значение NULL или whetever) и поместить значение в новом FlagColumn говорит вам тип проблем:

CASE WHEN ISNUMERIC(x)!=1 then NULL ELSE x END as x 
,CASE WHEN ISNUMERIC(x)!=1 then 'not numeric' else NULL END AS FlagColumn 

затем выбрать из новых преобразованных данных где FlagColumn НЕ NULL

вы можете попробовать использовать выберите заявления с IsNumeric() или IsDate() функции по различным столбцам исходных данных

EDIT

Существует много полей даты. В таблице 2, имеются значения данных, такие как '02/05/1075 'для даты рождения. Я хочу, чтобы рассмотрел каждую строку, которая вызывает ошибку , поэтому я могу сообщить в отдел , ответственный за плохие данные , чтобы они могли исправить его.

Используйте это, чтобы вернуть все плохие строки даты:

SELECT * FROM YourTable WHERE ISDATE(YourDateColumn)!=1 
5

Это не способ сделать это с SSIS. У вас должен быть поток данных из вашего источника, в пункт назначения, с любыми преобразованиями, которые вам нужны в середине. Вы сможете получить данные об ошибках и, фактически, строки ошибок, используя вывод ошибки адресата.

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


На самом деле, если вы сделаете это стандартный способ в SSIS, то несоответствие типов данных должны быть обнаружены во время разработки.

0

У Джона Саудера есть правильная идея, есть более эффективные способы обработки такого рода с использованием SSIS. Тем не менее, изучение SSIS и переделка вашего пакета для полного изменения процесса могут не быть вариантом в настоящее время, поэтому я предлагаю этот совет. У вас возникли проблемы с неправильными датами. Поэтому сначала запустите запрос, чтобы определить те записи, которые являются плохими, и вставьте их в таблицу исключений. Затем вы вставляете только те записи, которые остались. Что-то вроде:

insert exceptiontable (field1, field2) 
select field1, field2 from table2 where isdate(field2) = 0 

insert table1 (field1, field2) 
select field1, field2 from table2 where isdate(field2) = 1 

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

+0

Он сказал, что уже использует SSIS, а Source -> Dest -> Error не очень сложно ... –

+0

Я согласен, вот как бы я это сделал, но SSIS нелегко научиться правильно пользоваться, и он может находиться под временным давлением. Я знаю, что, начиная с лет, когда я делаю пакеты DTS, этот метод никогда бы не подумал, если бы у меня не было официального обучения SSIS. Очевидно, что он использует сценарии t-sql, а не поток данных, поэтому он может совершенно не знать, как использовать поток данных. Это нелегко в первый раз, когда вы это сделаете. – HLGEM

+0

Знаете, мне никогда не приходило в голову, что он может использовать SSIS и не использовать поток данных. –

2

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

select row_number() over (order by TimeID) as rownum,timeID into #TestingTable from MyTableWithBadData 

set nocount on 
declare @row as int 
declare @last as int 
set @row=0 
select @last = count(*) from #TestingTable 
declare @timeid as decimal(24,0) 
create table #fails (rownum int) 
while @row<[email protected] 
begin 
    Begin Try 
     select @timeid=cast(timeID as decimal(24,0)) from #TestingTable where rownum = @row 
    end try 
    begin catch 
     print cast(@row as varchar(25)) + ' : failed' 
     insert into #fails(rownum) values(@row) 
    end catch 
    set @row = @row+1 
end 
Смежные вопросы