2015-12-26 81 views
0

我想知道,當我們用MERGE語句,然後如何,如果在記錄數據問題捕獲錯誤插入/更新大量數據的插入/更新大量XML數據時,捕捉到錯誤。如何使用MERGE語句

查看示例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是整數類型和我們插入字母數字值,以便插入將是不可能的。我想寫一個存儲過程,以便它應該保存錯誤日誌的詳細信息。所以稍後當我們看到錯誤日誌時,可以很容易地理解問題是什麼或問題在哪裏。

請看下面一個例子:

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); 

請指引我在細節。由於

回答

0

一種方法是用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.  ║ 
╚════╩═════════════════════╩═════════════════════════════════════════════╝ 
+0

偉大的,但我們可以捕捉它具有數據錯誤的行? – Thomas

+0

@Thomas在插入前沒有寫入自定義代碼來驗證數據,沒有。請注意,SQL Server錯誤消息僅爲您提供有關值的詳細信息。您可以在提供的XML中搜索值「3A」。請記住,MERGE是全有或全無的。所以如果有一個錯誤沒有記錄將被插入/更新 – lad2025