我正在尝试使用BULK INSERT
收集文件中包含的所有格式和约束错误。我希望文件中的确切行代表每个错误和错误描述。
目前,我使用ERRORFILE
选项收集文件中包含的所有格式错误。这给了我我需要的东西,但仅用于格式化错误。
我想对约束错误做同样的事情。如果我使用CHECK_CONSTRAINTS
选项,我可以捕获错误,但批量插入终止。在检测到约束违规后,批量插入是否有任何方法可以继续插入行,以便我可以收集所有约束错误?
我可以对插入行的临时表进行约束检查(批量插入完成后),但我不想遵循这种方法,因为:
更新
输入文件是制表符分隔的文本文件,包含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='''+@ErrorFilePath+''')'
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 :(得分: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