我第一次尝试将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
答案 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输入,您有两个属性 - id
和name
(并且您在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)