【问题标题】:SQL Capture BULK INSERT error 4863SQL 捕获批量插入错误 4863
【发布时间】:2013-12-03 16:20:12
【问题描述】:

我在 try - catch 块中有一个大容量插入:

BEGIN TRY
    BULK INSERT dbo.EQUIP_STATUS_CODE
    FROM 'filepath\filename.csv'
    WITH ( MAXERRORS = 1,  FIELDTERMINATOR = ',')
END TRY 
BEGIN CATCH
    EXECUTE  dbo.ERROR_LOG_CSV;
END CATCH

我希望能够在发生以下错误时捕获它:

批量加载数据转换错误(截断)

但我似乎不能,即使级别是 16,属于 try-catch 范围。我想知道是否有办法在发生此错误时捕获它。

在我将 MAXERRORS 指定为 1 之前,我收到了这个错误:

无法从链接服务器“(null)”的 OLE DB 提供程序“BULK”获取行。

由于前一个错误更能描述问题,这就是我想记录的错误。

【问题讨论】:

    标签: sql-server error-handling try-catch


    【解决方案1】:

    虽然我的能力比 SQL Server 更擅长 Oracle,但无论如何我会尝试以某种方式帮助解决这个问题。我发现您的情况自 2010 年以来已经在 SQL Server 的 bugtracker(错误 id:592960)中,状态为“不会修复”。您可以自己查看connect.microsoft.com 上的相应讨论(目前主机无法访问,所以我用google cache)。

    【讨论】:

      【解决方案2】:

      Alexander 已经给了您答案,但您必须非常仔细地阅读错误日志并考虑可能发生的情况。 SQL Server(错误 ID:592960)

      您正在尝试直接从数据文件批量插入到数据表中?

      从文章中可以看出,数据类型不匹配或截断。 SQL 引擎有一个错误,不会将此报告为错误。

      引用报告错误的第一人 - “尽管严重级别为 16,但我没有看到 TRY / CATCH 构造捕获的错误。代码不会中断并且顺利进行,就像没有错误一样已经发生了。”

      您是否调查过哪些字段可能包含不良数据?

      这里有一些建议。

      1 - 逗号分隔的文件有问题 - 我一直讨厌逗号分隔的格式,因为逗号可以在数据流中。尝试使用波浪号 ~ 作为不经常出现的分隔符。问题可能是文本字段中有逗号吗?从而在数据流中添加一个字段?

      2 - 使用暂存表 - 有时最好将文件中的数据导入暂存表,该暂存表的列定义为 varchar (x)。这允许数据进入表中。

      然后编写一个存储过程来验证列中的数据,然后再传输到生产表。将任何坏行标记为可疑。

      将暂存表中的数据插入生产环境,留下任何错误行。

      发送电子邮件让某人查看不良数据。如果这是重复发生的数据文件传输,您需要从源头修复它。

      3 - 使用 ETL 工具重写过程 - 跳过在引擎中编写这些内容。 SQL Server Integration Services (SSIS) 是一个出色的提取翻译加载 (ETL) 工具。

      连接中有选项可以声明文本被引用“”,消除了上述额外的逗号问题。您可以将无法导入生产表的行发送到医院表进行审核。

      总而言之,引擎有BUG。

      但是,我肯定会考虑更改为波浪号格式的文件和/或使用临时表。更好的是,如果您有时间,请使用 SSIS 包重写该过程!

      真诚的

      J

      PS:我给 Alexander 积分,因为他确实发现了 SQL 连接的错误。但是,我认为文件的格式是根本原因。

      【讨论】:

        【解决方案3】:

        这可能会捕捉到这个错误,因为它捕捉到错误消息 4860:

        问: TRY doesn't CATCH error in BULK INSERT

        BEGIN TRY
          DECLARE @cmd varchar(1000)
          SET @cmd = 'BULK INSERT [dbo].[tblABC] 
          FROM ''C:\temp.txt'' 
          WITH (DATAFILETYPE = ''widechar'',FIELDTERMINATOR = '';'',ROWTERMINATOR = ''\n'')'
          EXECUTE (@cmd)
        END TRY
        
        BEGIN CATCH
         select error_message()
        END CATCH
        

        【讨论】:

          猜你喜欢
          • 2023-03-03
          • 2021-07-17
          • 1970-01-01
          • 1970-01-01
          • 2019-11-13
          • 2012-10-26
          • 1970-01-01
          • 2017-04-09
          • 1970-01-01
          相关资源
          最近更新 更多