有人可以帮我解析T-SQL中的以下XML(SQL Server 2005)吗?
<Tx>
<T>1</T>
<C>1</C>
<T>2</T>
<C>1</C>
<T>3</T>
<C>1</C>
<T>4</T>
<C>1</C>
</Tx>
我尝试了以下内容:
SELECT
Tx.query('T').value('.', 'varchar(10)') AS [Column 1],
Tx.query('C').value('.', 'varchar(10)') AS [Column 2]
FROM @MyXml.nodes('Tx') x(Tx)
但它不起作用,因为我得到以下结果:
Column 1 Column 2
-------- --------
1234 1111
期待(我想要实现的目标):
Column 1 Column 2
-------- --------
1 1
2 1
3 1
4 1
该字符串显然是一个有效的XML,但它对T-SQL有效吗?
如果有人能提供解释XML如何在T-SQL中工作的参考,我将不胜感激。
提前致谢。
答案 0 :(得分:5)
这是一种按位置配对值的方法。第一个T与第一个C匹配,依此类推。
declare @XML xml =
'<Tx>
<T>1</T>
<C>4</C>
<T>2</T>
<C>3</C>
<T>3</T>
<C>2</C>
<T>4</T>
<C>1</C>
</Tx>'
select @XML.value('(/Tx/T[position() = sql:column("N.number")])[1]', 'int') as Column1,
@XML.value('(/Tx/C[position() = sql:column("N.number")])[1]', 'int') as Column2
from master..spt_values as N
where N.type = 'P' and
N.number between 1 and @XML.value('max((count(/Tx/T), count(/Tx/C)))', 'int')
使用suggested marc_s之类的XML的不同结构,查询更多更简单。
declare @XML xml =
'<Tx>
<row>
<T>1</T>
<C>4</C>
</row>
<row>
<T>2</T>
<C>3</C>
</row>
<row>
<T>3</T>
<C>2</C>
</row>
<row>
<T>4</T>
<C>1</C>
</row>
</Tx>'
select T.R.value('T[1]', 'int') as Column1,
T.R.value('C[1]', 'int') as Column2
from @XML.nodes('/Tx/row') as T(R)
答案 1 :(得分:3)
你想要实现什么?
您当前的select语句会列出<T>
下面的所有<Tx>
元素 - 但只列出那些 - 而不是<C>
节点 - 并且您似乎想从中获取值两种子节点 - 右??
这将为您提供<T>
节点中的所有元素 - 您正在寻找什么?
SELECT
Tx.x.value('.', 'varchar(10)') AS [Column 1]
FROM @MyXml.nodes('Tx/T') Tx(x)
这将为您提供<Tx>
节点内的所有元素,包括它们的“类型”(C或T) - 您正在寻找什么?
SELECT
ColumType = Tx.x.value('local-name(.)', 'varchar(10)'),
ColumnValue = Tx.x.value('.', 'varchar(10)')
FROM @MyXml.nodes('Tx/*') Tx(x)
更新:作为学习如何在SQL Server中使用XQuery的资源,我建议
你的XML并不适合做你想要做的事情 - 没有任何东西可以“整合”明显属于一起的T和C元素 - 所以XQuery根本没有办法按你想要的方式解析它它来。
如果你有这样的XML:
<Tx>
<Pair>
<T>....</T>
<C>....</C>
</Pair>
<Pair>
<T>....</T>
<C>....</C>
</Pair>
....
</Tx>
然后你可以获得Tx/Pair
个节点的列表,并从该XML片段中获取T和C元素。但是现在 - 您所能做的就是解析<Tx>
的所有8个子节点并显示它们的值 - 这就是您所能做的一切
答案 2 :(得分:3)
使用此:
select a.t, b.c
from
(
select t.c.value('.[1]', 'int') [t]
, ROW_NUMBER() OVER(ORDER BY t.c) [rn]
from @MyXml.nodes('Tx/T') t(c)
)a
join
(
select t.c.value('.[1]', 'int') [c]
, ROW_NUMBER() OVER(ORDER BY t.c) [rn]
from @MyXml.nodes('Tx/C') t(c)
)b on b.rn = a.rn
或其他方式:
select t.t [T]
, @MyXml.value('(Tx/C[position() = sql:column("rn")])[1]', 'int') [C]
from
(
select t.c.value('.[1]', 'int') [t]
, ROW_NUMBER() OVER(ORDER BY t.c) [rn]
from @MyXml.nodes('Tx/T') t(c)
)t