【问题标题】:How to capture error when insert/update bulk xml data using merge statement使用合并语句插入/更新批量 xml 数据时如何捕获错误
【发布时间】:2015-12-26 10:50:02
【问题描述】:

我想知道当我们使用合并语句插入/更新批量数据时,如果记录数据出现问题,如何捕获错误。

查看示例 xml:

<?xml version = "1.0" encoding="UTF-8" standalone="yes"?>
<document>
  <employee>
  <id>1</id>
  <name>test1</name>
  <salary>2000</salary>
  </employee>
  <employee>
  <id>2</id>
  <name>test2</name>
  <salary>4000</salary>
  </employee>
  <employee>
  <id>3A</id>
  <name>test3</name>
  <salary>8000</salary>
  </employee>
</document>

这是错误 3A id is int type,我们正在插入字母数字值,因此无法插入。我想以这样的方式编写一个存储过程,它应该详细保存错误日志。所以稍后当我们看到错误日志时,就可以很容易地了解问题出在哪里或问题出在哪里。

请看下面的示例:

CREATE TABLE [employee]
(
    [id]        INT,
    [name]      NVARCHAR(100),
    [salary]    INT,
)
GO

DECLARE @XML XML ='<?xml version = "1.0" encoding="UTF-8" standalone="yes"?>
<document>
  <employee>
  <id>1</id>
  <name>test1</name>
  <salary>2000</salary>
  </employee>
  <employee>
  <id>2</id>
  <name>test2</name>
  <salary>4000</salary>
  </employee>
  <employee>
  <id>3</id>
  <name>test3</name>
  <salary>8000</salary>
  </employee>
</document>'
MERGE employee AS [target]
USING   
(
    SELECT   
         tab.col.value('id[1]','int') as id
        ,tab.col.value('name[1]','nvarchar(100)') as name
        ,tab.col.value('salary[1]','int') as salary              
    FROM @xml.nodes('//employee') AS tab(col) 
) 
 AS [source] (id,name,salary) ON ([target].[id] = [source].[id])
        WHEN MATCHED THEN 
        UPDATE 
        SET 
            [target].[name]     = [source].[name],
            [target].[salary]   = [source].[salary]              
        WHEN NOT MATCHED THEN       
            INSERT (id,name,salary) 
                VALUES ([source].id,[source].name,[source].salary);

请详细指导我。谢谢

【问题讨论】:

    标签: sql-server xml xquery-sql


    【解决方案1】:

    一种方法是使用TRY/CATCH 块包装您的代码并将数据记录到error_table:

    结构:

    CREATE TABLE #employee
    (
        [id]        INT,
        [name]      NVARCHAR(100),
        [salary]    INT,
    );
    
    CREATE TABLE #error_log(ID INT IDENTITY(1,1),
                            create_date DATETIME NOT NULL DEFAULT GETDATE(),
                            message NVARCHAR(1000));
    
    
    DECLARE @XML XML ='<?xml version = "1.0" encoding="UTF-8" standalone="yes"?>
    <document>
      <employee>
      <id>1</id>
      <name>test1</name>
      <salary>2000</salary>
      </employee>
      <employee>
      <id>2</id>
      <name>test2</name>
      <salary>4000</salary>
      </employee>
      <employee>
      <id>3A</id>
      <name>test3</name>
      <salary>8000</salary>
      </employee>
    </document>';
    

    代码:

    BEGIN TRY
    
      MERGE #employee AS [target]
      USING   
      (
        SELECT   
             tab.col.value('id[1]','int') as id
            ,tab.col.value('name[1]','nvarchar(100)') as name
            ,tab.col.value('salary[1]','int') as salary              
        FROM @xml.nodes('//employee') AS tab(col) 
      ) 
       AS [source] (id,name,salary) ON ([target].[id] = [source].[id])
            WHEN MATCHED THEN 
            UPDATE 
            SET 
                [target].[name]     = [source].[name],
                [target].[salary]   = [source].[salary]              
            WHEN NOT MATCHED THEN       
                INSERT (id,name,salary) 
                    VALUES ([source].id,[source].name,[source].salary);
    END TRY
    BEGIN CATCH
      INSERT INTO #error_log(message)
      VALUES (ERROR_MESSAGE());
    END CATCH
    
    SELECT *
    FROM #error_log
    
    SELECT *
    FROM #employee
    

    LiveDemo

    输出:

    ╔════╦═════════════════════╦═════════════════════════════════════════════╗
    ║ ID ║     Create_date     ║                   message                   ║
    ╠════╬═════════════════════╬═════════════════════════════════════════════╣
    ║  1 ║ 2015-12-26 11:04:12 ║ Conversion failed when converting the       ║
    ║    ║                     ║ nvarchar value '3A' to data type int.       ║
    ╚════╩═════════════════════╩═════════════════════════════════════════════╝
    

    【讨论】:

    • 很好,但我们可以捕获数据有错误的行吗?
    • @Thomas 在插入之前不编写自定义代码来验证数据,不。请注意,SQL Server 错误消息只为您提供有关值的详细信息。您可以在提供的 XML 中搜索值 3A。请记住,MERGE 是全有或全无。因此,如果出现一个错误,则不会插入/更新任何记录
    猜你喜欢
    • 2022-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多