使用OPENROWSET和OPENXML将XML导入SQL Server

时间:2016-08-22 17:57:49

标签: sql-server xml openxml openrowset

以前从未这样做过,似乎有命名空间问题?任何帮助,将不胜感激。如果我从XML文件中删除xmlns属性,它可以正常工作......

示例XML:

<?xml version="1.0" encoding="UTF-8"?>
<ETS xsi:schemaLocation="http://www.caodc.ca/ETS/v3 ETS_v3.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.caodc.ca/ETS/v3">
<WellTours>
<WellTour>
<LicenseNo>001</LicenseNo>
<WellName>75-998</WellName>
</WellTour>
<WellTour>
<LicenseNo>007</LicenseNo>
<WellName>14-172</WellName>
</WellTour>
</WellTours>
</ETS>

这是我的SQL:

DECLARE @xml xml

SELECT @xml=I
FROM OPENROWSET (BULK 'C:\CCTESTFILE.XML', SINGLE_BLOB) as ImportFile(I)

SELECT @xml

DECLARE @hdoc int

EXEC sp_xml_preparedocument @hdoc OUTPUT, @xml

SELECT *
FROM OPENXML (@hdoc, '/ETS/WellTours/WellTour',2)
WITH (
        WellName varchar(100),
        LicenseNo varchar(100));

EXEC sp_xml_removedocument @hdoc

2 个答案:

答案 0 :(得分:1)

使用内置的 XQuery 功能更简单,而不是使用旧的,笨重且内存泄漏的OPENXML方法:

;WITH XMLNAMESPACES(DEFAULT 'http://www.caodc.ca/ETS/v3')
SELECT
    LicenseNo = XC.value('(LicenseNo)[1]', 'varchar(10)'),
    WellName = XC.value('(WellName)[1]', 'varchar(25)')
FROM
    @xml.nodes('/ETS/WellTours/WellTour') AS XT(XC)

给我一​​个输出:

enter image description here

答案 1 :(得分:0)

如果出于某种原因必须使用openxml,则需要向sp_xml_preparedocument调用添加名称空间声明。这样的事情。

declare @xml varchar(max)= --no need to declare as xml
'<?xml version="1.0" encoding="UTF-8"?>
<ETS xsi:schemaLocation="http://www.caodc.ca/ETS/v3 ETS_v3.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.caodc.ca/ETS/v3">
<WellTours>
<WellTour>
<LicenseNo>001</LicenseNo>
<WellName>75-998</WellName>
</WellTour>
<WellTour>
<LicenseNo>007</LicenseNo>
<WellName>14-172</WellName>
</WellTour>
</WellTours>
</ETS>'

DECLARE @hdoc int

--Note x: before ETS and :x after xmlns
EXEC sp_xml_preparedocument @hdoc OUTPUT, @xml, '<x:ETS xmlns:x="http://www.caodc.ca/ETS/v3" />'

--Note x: before elements
SELECT *
FROM OPENXML (@hdoc, 'x:ETS/x:WellTours/x:WellTour',2)
WITH (
        WellName varchar(100) 'x:WellName',
        LicenseNo varchar(100) 'x:LicenseNo');

EXEC sp_xml_removedocument @hdoc