2016-08-03 2 views
3

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

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

Я хочу сделать то же самое с ошибками ограничения. Если я использую опцию CHECK_CONSTRAINTS, я могу поймать ошибку, но объемная вставка завершается. Есть ли способ, чтобы объемная вставка продолжала вставлять строки после обнаружения нарушения ограничений, чтобы я мог собирать все ошибки ограничения?

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

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

Update

Входной файл представляет собой табуляцией текстовый файл с 3-мя столбцами: ID, название, описание

Ниже приведен код, который я использую для чтения/проверки файла:

create table #MyTable (ID int not null, Name varchar(20) not null, Description varchar(60) not null) 

alter table #MyTable add check (ID != 1) 

begin try 
    execute sp_executesql 'bulk insert #MyTable from ''' + @FilePath + ''' with (maxerrors = 1000,check_constraints,errorfile='''[email protected]+''')' 
end try 
begin catch 
-- Here I am logging the constraint validation error 
end catch 

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

RowNumber int, ErrorDescription nvarchar(max) not null 

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

+0

Я думаю, вы можете пропустить все строки файла самостоятельно и выполнить каждую команду вставки в блоке try catch. Это не будет быстрым, но с миллионами строк ничего нет – GuidoG

ответ

0

Недавно мне пришлось импортировать сотни тысяч XML-файлов, каждая из которых содержала ровно одну строку. Мой подход заключался в том, чтобы получить на первом этапе все файлы в базе данных, а затем выполнить проверки длины текста, ограничений, диапазонов значений, проблем с преобразованием ... При выполнении этого подхода вам необходимо объявить типы данных всех столбцов как nvarchar (max) позволяя хранить все данные во временной таблице. Вы никогда не узнаете, что получите. Эта таблица содержит всю информацию, необходимую для выполнения ваших проверок, для идентификации ошибочных записей, преобразования и записи преобразованных данных в таблицу назначения с помощью одного оператора SQL.

CREATE TABLE #MyTable1 ([ID] varchar(max), [NAME] varchar(max), [DESCRIPTION] varchar(max)); 
CREATE TABLE #MyTable2 ([ID] int not null, [NAME] varchar(20) not null, [DESCRIPTION] varchar(60) not null); 

EXEC sp_executesql 'bulk insert #MyTable from ''' + @FilePath + '''' 
--> I'm not so familiar wit the right syntax. I hope it is right. The point is, don't do any checks here. 

SELECT 
    TRY_CONVERT([ID]) 
    ,[NAME] 
    ,[DESCRIPTION] 
    --,CASE WHEN TRY_CONVERT([ID]) IS NULL AND [ID] IS NOT NULL  THEN 1 ELSE 0 END AS [CONVERSION_ERROR_ID] 
    --,CASE WHEN [NAME] IS NOT NULL AND LEN([NAME]) > 20    THEN 1 ELSE 0 END AS [CONVERSION_NAME] 
    --,CASE WHEN [DESCRIPTION] IS NOT NULL AND LEN([DESCRIPTION]) > 60 THEN 1 ELSE 0 END AS [CONVERSION_DESCRIPTION] 
FROM 
    #MyTable1 
WHERE 
     CASE WHEN TRY_CONVERT([ID]) IS NULL AND [ID] IS NOT NULL  THEN 1 ELSE 0 END = 1 -- 
    OR CASE WHEN [NAME] IS NOT NULL AND LEN([NAME]) > 20    THEN 1 ELSE 0 END = 1 -- --> show only erroneous rows 
    OR CASE WHEN [DESCRIPTION] IS NOT NULL AND LEN([DESCRIPTION]) > 60 THEN 1 ELSE 0 END = 1 -- 
    -- Insert additional checks concerning the not null settings 


INSERT #MyTable2 ([ID], [NAME], [DESCRIPTION]) 
SELECT 
    [ID] 
    ,[NAME] 
    ,[DESCRIPTION] 
FROM 
    #MyTable1 
WHERE 
     CASE WHEN TRY_CONVERT([ID]) IS NULL AND [ID] IS NOT NULL  THEN 1 ELSE 0 END = 0 -- 
    AND CASE WHEN [NAME] IS NOT NULL AND LEN([NAME]) > 20    THEN 1 ELSE 0 END = 0 -- --> Write only those rows to #MyTable2 where no issues can be found 
    AND CASE WHEN [DESCRIPTION] IS NOT NULL AND LEN([DESCRIPTION]) > 60 THEN 1 ELSE 0 END = 0 -- 
    -- Insert additional checks concerning the not null settings 

-- Please note, that I have not tested these statements 
Смежные вопросы