我有一个填充了XML数据的表,我正在尝试解析。 XML包含我试图解析的多列数据。在某些情况下,有多行XML数据填充到单列数据中,在某些情况下只有一行。以下样本数据:
<REC><C1>0E5627DF-DBB1-4300-40F2-715A8C96190B</C1><C2>apples</C2></REC>
<REC><C1>59868DA4-DB9D-1384-B07D-715A8C96197B</C1><C2>oranges</C2></REC><REC><C1>59868DA4-DB9D-1384-B07D-715A8C96197B</C1><C2>grapes</C2></REC><REC><C1>59868DA4-DB9D-1384-B07D-715A8C96197B</C1><C2>apples</C2></REC>
<REC><C1>7FB8C203-DB30-5340-B07D-715A8C9619FA</C1><C2>bananas</C2></REC><REC><C1>7FB8C203-DB30-5340-B07D-715A8C9619FA</C1><C2>watermelon</C2></REC><REC><C1>7FB8C203-DB30-5340-B07D-715A8C9619FA</C1><C2>limes</C2></REC>
<REC><C1>38B13BFB-DBAA-C340-40F2-715A8C961942</C1><C2>apples</C2></REC>
<REC><C1>58209738-DB3C-DB00-D01A-7FDA8C9619B5</C1><C2>pears</C2></REC><REC><C1>58209738-DB3C-DB00-D01A-7FDA8C9619B5</C1><C2>limes</C2></REC>
我要做的是将数据解析为以下2列布局
C1 C2
0E5627DF-DBB1-4300-40F2-715A8C96190B apples
59868DA4-DB9D-1384-B07D-715A8C96197B oranges
59868DA4-DB9D-1384-B07D-715A8C96197B grapes
59868DA4-DB9D-1384-B07D-715A8C96197B apples
7FB8C203-DB30-5340-B07D-715A8C9619FA bananas
7FB8C203-DB30-5340-B07D-715A8C9619FA watermelon
7FB8C203-DB30-5340-B07D-715A8C9619FA limes
38B13BFB-DBAA-C340-40F2-715A8C961942 apples
58209738-DB3C-DB00-D01A-7FDA8C9619B5 pears
58209738-DB3C-DB00-D01A-7FDA8C9619B5 limes
以下是我的尝试:
SELECT Split.XMLD.value('.', 'VARCHAR(500)')
FROM myTable XMLD
CROSS APPLY XMLD.REC.nodes ('/REC') AS Split(XMLD)
任何想法如何解析这个?
澄清:我想在这里继续使用Native MS SQL SQL。我不想使用任何第三方工具。
答案 0 :(得分:2)
试试这个:
DECLARE @mockupTable TABLE (ID INT IDENTITY, YourXml XML);
INSERT INTO @mockupTable VALUES
('<REC><C1>0E5627DF-DBB1-4300-40F2-715A8C96190B</C1><C2>apples</C2></REC>')
,('<REC><C1>59868DA4-DB9D-1384-B07D-715A8C96197B</C1><C2>oranges</C2></REC><REC><C1>59868DA4-DB9D-1384-B07D-715A8C96197B</C1><C2>grapes</C2></REC><REC><C1>59868DA4-DB9D-1384-B07D-715A8C96197B</C1><C2>apples</C2></REC>')
,('<REC><C1>7FB8C203-DB30-5340-B07D-715A8C9619FA</C1><C2>bananas</C2></REC><REC><C1>7FB8C203-DB30-5340-B07D-715A8C9619FA</C1><C2>watermelon</C2></REC><REC><C1>7FB8C203-DB30-5340-B07D-715A8C9619FA</C1><C2>limes</C2></REC>')
,('<REC><C1>38B13BFB-DBAA-C340-40F2-715A8C961942</C1><C2>apples</C2></REC>')
,('<REC><C1>58209738-DB3C-DB00-D01A-7FDA8C9619B5</C1><C2>pears</C2></REC><REC><C1>58209738-DB3C-DB00-D01A-7FDA8C9619B5</C1><C2>limes</C2></REC>');
SELECT ID
,r.value(N'(C1/text())[1]','uniqueidentifier') AS C1
,r.value(N'(C2/text())[1]','nvarchar(max)') AS C2
FROM @mockupTable AS t
CROSS APPLY t.YourXml.nodes(N'/REC') AS A(r) ;
结果
+----+--------------------------------------+------------+
| ID | C1 | C2 |
+----+--------------------------------------+------------+
| 1 | 0E5627DF-DBB1-4300-40F2-715A8C96190B | apples |
+----+--------------------------------------+------------+
| 2 | 59868DA4-DB9D-1384-B07D-715A8C96197B | oranges |
+----+--------------------------------------+------------+
| 2 | 59868DA4-DB9D-1384-B07D-715A8C96197B | grapes |
+----+--------------------------------------+------------+
| 2 | 59868DA4-DB9D-1384-B07D-715A8C96197B | apples |
+----+--------------------------------------+------------+
| 3 | 7FB8C203-DB30-5340-B07D-715A8C9619FA | bananas |
+----+--------------------------------------+------------+
| 3 | 7FB8C203-DB30-5340-B07D-715A8C9619FA | watermelon |
+----+--------------------------------------+------------+
| 3 | 7FB8C203-DB30-5340-B07D-715A8C9619FA | limes |
+----+--------------------------------------+------------+
| 4 | 38B13BFB-DBAA-C340-40F2-715A8C961942 | apples |
+----+--------------------------------------+------------+
| 5 | 58209738-DB3C-DB00-D01A-7FDA8C9619B5 | pears |
+----+--------------------------------------+------------+
| 5 | 58209738-DB3C-DB00-D01A-7FDA8C9619B5 | limes |
+----+--------------------------------------+------------+
要考虑的一些事情:
答案 1 :(得分:0)
这是一种非常简洁的方法,可以轻松地为任何XML数据生成XQuery / XPath查询,无论复杂性或“丑陋”:
它需要SQLHTTP这是我们创建的免费数据库/程序集,您可以在我们的网站上找到它:http://sqlhttp.net/documentation/xqueryhelper
首先,您需要为数据设置XML变量。请注意,我添加了一个开始标记和结束标记。
DECLARE @X xml = '<ROOT>
<REC><C1>0E5627DF-DBB1-4300-40F2-715A8C96190B</C1><C2>apples</C2></REC>
<REC><C1>59868DA4-DB9D-1384-B07D-715A8C96197B</C1><C2>oranges</C2></REC><REC><C1>59868DA4-DB9D-1384-B07D-715A8C96197B</C1><C2>grapes</C2></REC><REC><C1>59868DA4-DB9D-1384-B07D-715A8C96197B</C1><C2>apples</C2></REC>
<REC><C1>7FB8C203-DB30-5340-B07D-715A8C9619FA</C1><C2>bananas</C2></REC><REC><C1>7FB8C203-DB30-5340-B07D-715A8C9619FA</C1><C2>watermelon</C2></REC><REC><C1>7FB8C203-DB30-5340-B07D-715A8C9619FA</C1><C2>limes</C2></REC>
<REC><C1>38B13BFB-DBAA-C340-40F2-715A8C961942</C1><C2>apples</C2></REC>
<REC><C1>58209738-DB3C-DB00-D01A-7FDA8C9619B5</C1><C2>pears</C2></REC><REC><C1>58209738-DB3C-DB00-D01A-7FDA8C9619B5</C1><C2>limes</C2></REC>
</ROOT>'
然后执行以下存储过程:
EXEC SQLHTTP.net.XqueryHelper @X
在这种情况下,程序将输出以下四行:
Usage Name Rows
------------------------------------------------- ------ ------
EXEC SQLHTTP.net.XQueryHelper @X, 'ROOT' ROOT 1
EXEC SQLHTTP.net.XQueryHelper @X, 'ROOT/REC' REC 10
EXEC SQLHTTP.net.XQueryHelper @X, 'ROOT/REC/C1' C1 10
EXEC SQLHTTP.net.XQueryHelper @X, 'ROOT/REC/C2' C2 10
您有兴趣获得带有水果名称的十条记录的第二行:
EXEC SQLHTTP.net.XQueryHelper @X, 'ROOT/REC'
上面的存储过程调用将输出你的XQuery / XPath:
SELECT T.C.value(N'C1[1]', N'nvarchar(MAX)') AS [C1]
,T.C.value(N'C2[1]', N'nvarchar(MAX)') AS [C2]
FROM @X.nodes(N'/ROOT/REC') T(C)