我是T-SQL和XQuery的新手。
我在DB中有XML列,结构如下
<GPC xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="...">
<GP>
<N>Amount1</N>
<V i:type="X_AMT">
<AMT>100001</AMT>
<X_CODE>Dollar</X_CODE>
</V>
</GP>
<GP>
<N>Amount2</N>
<V i:type="X_AMT">
<AMT>0</AMT>
<X_CODE />
</V>
</GP>
<GP>
<N>Amount3</N>
<V i:type="X_AMT">
<AMT>100001</AMT>
<X_CODE>Dollar</X_CODE>
</V>
</GP>
<GP>
<N>Amount4</N>
<V i:type="X_AMT">
<AMT>0</AMT>
<X_CODE />
</V>
</GP>
<GP>
<N>Amount5</N>
<V i:type="X_AMT">
<AMT>100001</AMT>
<X_CODE>Dollar</X_CODE>
</V>
</GP>
<GP>
**<N>NeededAmount</N>**
<V i:type="Y">
<DETAILS>
<REFERENCE>
<N>**ReferenceName1**</N>
<OId>111111</OId>
</REFERENCE>
</DETAILS>
<DETAILS>
<REFERENCE>
<N>**ReferenceName2**</N>
<OId>22222</OId>
</REFERENCE>
</DETAILS>
</V>
</GP>
...
</GPC>
这是我正在使用的SQL Server中的查询。 Query只返回一个名称 - Name1。 但是有两个名字,可以有100个名字,我想得到这些名字。
SELECT v.Content.query(N'declare default element namespace "...";
for $i in (GPC/GP) where ($i/N[1] eq "NeededAmount") return ($i)').value('declare default element namespace "...";
(GP/V/DETAILS/REFERENCE/N)[1]', 'nvarchar(max)') AS NeededName
FROM DB1.protected.WorkItem as v
where v.Id = 1111
我的问题是:如何修改此文件以获取文档中的所有名称?有人能帮助我吗?
提前致谢。
答案 0 :(得分:2)
尝试这样的事情:
;WITH XMLNAMESPACES(DEFAULT '...')
SELECT
Amount = XTbl.GP.value('(N)[1]', 'nvarchar(100)'),
NeededName = XTbl2.DetRef.value('(N)[1]', 'nvarchar(200)')
FROM
Table1 AS t
CROSS APPLY
t.XmlContent.nodes('/GPC/GP') AS XTbl(GP)
CROSS APPLY
XTbl.GP.nodes('V/DETAILS/REFERENCE') AS XTbl2(DetRef)
WHERE
wi.Id = 1111
答案 1 :(得分:0)
您需要使用nodes() Transact-SQL XML datatype method将xml“粉碎”成行。 nodes()方法用于FROM子句,并为xml文档中的每个匹配节点生成1行。
这是使用存储在变量中的xml的示例:
DECLARE @x XML
SET @x = N' <GPC xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" >
<GP>
<GP>
<N>Amount5</N>
<V i:type="X_AMT">
<AMT>100001</AMT>
<X_CODE>Dollar</X_CODE>
</V>
</GP>
<GP>
**<N>NeededAmount</N>**
<V i:type="Y">
<DETAILS>
<REFERENCE>
<N>**ReferenceName1**</N>
<OId>111111</OId>
</REFERENCE>
</DETAILS>
<DETAILS>
<REFERENCE>
<N>**ReferenceName2**</N>
<OId>22222</OId>
</REFERENCE>
</DETAILS>
</V>
</GP>
</GPC>
'
SELECT x.n.query('.') FROM @x.nodes('/GPC/GP/V/DETAILS/REFERENCE/N') AS x (n)
/* returns
<N>**ReferenceName1**</N>
<N>**ReferenceName2**</N> */
您还可以使用CROSS APPLY来粉碎表格中的xml列
CREATE TABLE #t (id INT, doc XML)
go
DECLARE @x XML
SET @x = N' <GPC xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" >
<GP>
<N>Amount5</N>
<V i:type="X_AMT">
<AMT>100001</AMT>
<X_CODE>Dollar</X_CODE>
</V>
</GP>
<GP>
**<N>NeededAmount</N>**
<V i:type="Y">
<DETAILS>
<REFERENCE>
<N>**ReferenceName1**</N>
<OId>111111</OId>
</REFERENCE>
</DETAILS>
<DETAILS>
<REFERENCE>
<N>**ReferenceName2**</N>
<OId>22222</OId>
</REFERENCE>
</DETAILS>
</V>
</GP>
</GPC>
'
INSERT INTO #t (id, doc) VALUES (1, @x)
INSERT INTO #t (id, doc) VALUES (2, @x)
SELECT t.id, x.n.query('.') RefName FROM #t t CROSS APPLY doc.nodes('/GPC/GP/V/DETAILS/REFERENCE/N') AS x (n)
--returns 4 rows, 2 for each document
/*
id RefName
1 <N>**ReferenceName1**</N>
1 <N>**ReferenceName2**</N>
2 <N>**ReferenceName1**</N>
2 <N>**ReferenceName2**</N> */