在SQL Server 2012中使用openXML

时间:2013-11-04 13:49:10

标签: sql-server sql-server-2012 openxml

我第一次尝试将openXML函数与SQL Server 2012一起使用,而且我遇到了一个问题。如果我有一个没有值的节点,即

<amenity id="bathtub" name="Bathtub" />

使用下面的代码从XML中提取数据时,我总是会返回一个NULL值。任何正常元素,即

<name>Attic Loft in a historical building</name>

似乎工作正常。有没有一种使用openXML检查节点是否存在的简单方法?

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)

SELECT @XML = XMLData FROM myXML

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML

SELECT *
FROM OPENXML(@hDoc, 'properties/property/amenities')
WITH 
(
name [nvarchar](250) '../name',
externalId [nvarchar](50) '../id',
externalURL [nvarchar](250) '../landing_page_url',
description [nvarchar](max) '../description',
bathtub [bit] 'bathtub '
)

EXEC sp_xml_removedocument @hDoc
GO

1 个答案:

答案 0 :(得分:3)

我会使用SQL Server内置的本机XQuery支持 - OpenXML陈旧,笨重,泄漏内存等等....

您可以使用@指标使用XPath表达式访问属性 - 如下所示:

DECLARE @input XML = '<amenity id="bathtub" name="Bathtub" />'

SELECT
    ID = @input.value('(/amenity/@id)[1]', 'varchar(50)'),
    Name = @input.value('(/amenity/@name)[1]', 'varchar(50)')

根据您的XML输入,您有两个属性 - idname(并且您在OpenXML示例中似乎无法调用bathtub)....)

<amenity id="bathtub" name="Bathtub" />
         ^^           ^^^^
         *            * 
         *            * --> attribute is called "name"
         *
         *--> attribute is called "id" (not "bathtub" - that's it's *value*, not the name!)

有关SQL Server 2005中XQuery支持的更多信息,请阅读以下文章:

更新:如果要迭代XML元素列表,请使用带有XPath表达式的.nodes()函数来获取XML片段列表,然后可以获取单个位来自 - 像这样:

DECLARE @input XML = '<properties><property><amenity id="bathtub" name="Bathtub" /></property><property><amenity id="pool" name="Big honking pool" /></property></properties>'

SELECT
    ID = XCol.value('(amenity/@id)[1]', 'varchar(50)'),
    Name = XCol.value('(amenity/@name)[1]', 'varchar(50)')
FROM
    @input.nodes('/properties/property') AS XTbl(XCol)