避免双XML INSERT到SQL

时间:2017-11-05 15:12:03

标签: sql-server xml

我需要将XML数据导入SQL Server 2012.导入工作正常,但我想避免双重导入。我已经尝试了WHERE NOT EXISTS,但它没有用。

导入:

INSERT INTO dbo.tXMLImport(cText)
SELECT cast(CONVERT(XML,x.BulkColumn,2) AS varchar(max))
FROM OPENROWSET (BULK 'D:\XML\Data.xml', SINGLE_BLOB) AS x

EXL文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<tOrder>
    <cName>Name1</cName>
    <cID>100</cID>
</tOrder>

现在,应该检查

中是否存在来自XML文件的 cID 100

dbo.tOrder cOrderNumber

    cOrderNumber
1   100
2   101
3   102

以下延伸不会w:

WHERE NOT EXISTS(SELECT * 
                FROM dbo.tOrder 
                WHERE x.value('(/tOrder/cID)') = dbo.tOrder.CorderNumber)

如果是,则不进行导入。也许有人可以支持我? 提前谢谢。

1 个答案:

答案 0 :(得分:1)

我不确定我是否真的得到了......如果已经存在相同的cOrderNumber,您是否不会尝试更新现有行?像你MERGE那样的东西?

但它可能是你想要的东西:

WHERE NOT EXISTS(SELECT 1 FROM dbo.tOrder
                 WHERE x.exist(N'/tOrder[cID/text()=sql:column("cOrderNumber")])')=1)

(未经测试的航空代码)

这会查看tOrder中是否有任何记录,其中XML列x出现了节点<tOrder><CID>,其值类似于当前cOrderNumber的值。

T-SQLsql:column()方法添加到XQuery,允许在查询中使用行的值。还有sql:variable()

xml的方法.exist()检查XML是否存在给定条件,并返回01

更新

再次阅读你的问题之后,我不确定我是否正确...请检查以下内容。如果这没有帮助,请使用我的代码设置独立示例以重新解决您的问题:

包含一些订单的虚拟表

DECLARE @YourTable TABLE(cOrderNumber INT, OrderName VARCHAR(100));
INSERT INTO @YourTable VALUES
 (100,'Order 100')
,(200,'Order 200')
,(300,'Order 300')

- 尝试插入包含现有OrderNumber=100

的XML
DECLARE @xml100 XML=
'<tOrder>
    <cName>Name1</cName>
    <cID>100</cID>
</tOrder>';

INSERT INTO @YourTable(cOrderNumber,OrderName)
SELECT @xml100.value('(/tOrder/cID/text())[1]','int')
      ,@xml100.value('(/tOrder/cName/text())[1]','varchar(100)')
WHERE NOT EXISTS(SELECT 1 FROM @YourTable AS t2 
                 WHERE t2.cOrderNumber=@xml100.value('(/tOrder/cID/text())[1]','int'));

- 与上面的代码相同,但订单号现在是不存在的数字

DECLARE @xml101 XML=
'<tOrder>
    <cName>Name1</cName>
    <cID>101</cID>
</tOrder>';

INSERT INTO @YourTable(cOrderNumber,OrderName)
SELECT @xml101.value('(/tOrder/cID/text())[1]','int')
      ,@xml101.value('(/tOrder/cName/text())[1]','varchar(100)')
WHERE NOT EXISTS(SELECT 1 FROM @YourTable AS t2 
                 WHERE t2.cOrderNumber=@xml101.value('(/tOrder/cID/text())[1]','int'));

- 检查结果

SELECT *
FROM @YourTable;

nr  name
-------------
100 Order 100
200 Order 200
300 Order 300
101 Name1