我正在尝试使用 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
行为)。
最佳答案
最近我不得不导入数十万个 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
关于sql-server - 批量插入 - 捕获所有约束错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38740391/