我想知道何时使用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是int类型,我们正在插入字母数字值,因此无法插入。我想以这样的方式编写存储过程,它应该详细保存错误日志。所以稍后当我们看到错误日志时,可以很容易地理解问题是什么或问题出在哪里。
请看下面的例子:
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 :(得分: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. ║
╚════╩═════════════════════╩═════════════════════════════════════════════╝