我想将XML字段'拆分'到多列数据集。 XML看起来像:
<simple>
<propertyid>
<value>p1</value>
<value>p2</value>
<value>p3</value>
<value>p4</value>
</propertyid>
<complexid>
<value>c1</value>
<value>c2</value>
<value>c3</value>
</complexid>
</simple>
我尝试做类似的事情(每次我在TSQL中使用XML时都感觉像是butthurt,所以我的代码错了):
;WITH source AS (
SELECT CAST(@xmlstring AS XML) AS x
)
SELECT
items.item.query('.')
FROM source
CROSS APPLY x.nodes('/simple/*/value') AS items(item)
预期数据集:
ColumnName Value
------------------------
propertyid p1
propertyid p2
propertyid p3
propertyid p4
complexid c1
complexid c2
complexid c3
我如何获得所需的结果? 也许你可以推荐使用T-SQL + XML + XQuery解释和样本的好资源吗?
答案 0 :(得分:5)
尝试这样的事情:
;WITH source AS (
SELECT CAST(@xmlstring AS XML) AS x
)
SELECT
ColumnName = XTbl.Parent.value('local-name(.)', 'varchar(50)'),
[Value] = XTbl2.ChildValues.value('(.)[1]', 'varchar(20)')
FROM source
CROSS APPLY
x.nodes('/simple/*') AS XTbl(Parent)
CROSS APPLY
XTbl.Parent.nodes('value') AS XTbl2(ChildValues)
这对你有用吗?我得到了所需的输出(使用帮助表)。
答案 1 :(得分:3)
这是我自己的解决方案1 CROSS APPLY:
;WITH source AS (
SELECT CAST(@xmlstring AS XML) AS x
)
SELECT
items.item.value('local-name(..)', 'varchar(300)') AS ColumnName,
items.item.value('text()[1]', 'varchar') AS Value
FROM source
CROSS APPLY x.nodes('/simple/*/value') AS items(item)
主要是我无法访问父节点,我尝试使用'../ local-name()',但local-name()需要XPath来显示名称。在那之后,父母节点名称变得容易。
答案 2 :(得分:1)
当您请求XQuery解决方案的建议时,这里是:
declare function local:createTestDoc() as node()* {
<simple>
<propertyid>
<value>p1</value>
<value>p2</value>
<value>p3</value>
<value>p4</value>
</propertyid>
<complexid>
<value>c1</value>
<value>c2</value>
<value>c3</value>
</complexid>
</simple>
};
declare function local:doProcessing($arg as node()*) as xs:string* {
let $simpleElement := $arg
return (
concat("ColumnName", " ", "Value")
,
for $propertyId in $simpleElement/propertyid/*
return (
concat("propertyid", " ", data($propertyId))
)
,
for $complexId in $simpleElement/complexid/*
return (
concat("complexid", " ", data($complexId))
)
)
};
local:doProcessing(local:createTestDoc())
您必须使用以下内容包含文档,而不是使用local:createTestDoc()。
declare variable $myDoc := doc("urlToDoc");
并将其传递给local:doProcessing()fn。
local:doProcessing($myDoc)