【发布时间】:2018-02-28 22:16:46
【问题描述】:
我有以 XML 格式存储的数据,它的结构更像是一种 HTML 格式,而不是真正的 XML。元素头包含列名,行元素包含这些列的数据。
<root>
<head>
<value>DeviceID</value>
<value>VolumeName</value>
<value>SizeGB</value>
<value>FreeSpaceGB</value>
<value>FreeSpacePercent</value>
</head>
<row>
<value>C:</value>
<value>c$OS-COMPUTER01</value>
<value>126</value>
<value>43</value>
<value>34</value>
</row>
<row>
<value>D:</value>
<value>D$DB-COMPUTER01</value>
<value>127</value>
<value>104</value>
<value>82</value>
</row>
<row>
<value>E:</value>
<value>E$COMPUTER01</value>
<value>127</value>
<value>106</value>
<value>84</value>
</row>
</root>
这里的问题是,这只是我拥有的收藏品之一。还有其他集合项,它们具有相同的格式,但可能列数不同,因此我不能将列名硬编码到 select 语句中。此外,某些值可以为空。 其他收藏品示例如下:
<data>
<head>
<value>FriendlyName</value>
<value>DnsNameList</value>
<value>NotAfter</value>
<value>NotBefore</value>
<value>Thumbprint</value>
<value>Issuer</value>
</head>
<row>
<value />
<value />
<value>08/23/2021 07:59:59</value>
<value>08/23/2011 08:00:00</value>
<value>E1A7D7E3BD6CA0C832182248EF7F092A72F9EB67</value>
<value>CN=Hewlett-Packard Private Class 2 Certification Authority, O=Hewlett-Packard Company, C=US, OU=IT Infrastructure, O=hp.com</value>
</row>
<row>
<value>Microsoft Root Certificate Authority</value>
<value />
<value>05/10/2021 07:28:13</value>
<value>05/10/2001 07:19:22</value>
<value>CDD4EEAE6000AC7F40C3802C171E30148030C072</value>
<value>CN=Microsoft Root Certificate Authority, DC=microsoft, DC=com</value>
</row>
<row>
<value>Thawte Timestamping CA</value>
<value />
<value>01/01/2021 07:59:59</value>
<value>01/01/1997 08:00:00</value>
<value>BE36A4562FB2EE05DBB3D32323ADF445084ED656</value>
<value>CN=Thawte Timestamping CA, OU=Thawte Certification, O=Thawte, L=Durbanville, S=Western Cape, C=ZA</value>
</row>
<row>
<value>Microsoft Root Authority</value>
<value />
<value>12/31/2020 15:00:00</value>
<value>01/10/1997 15:00:00</value>
<value>A43489159A520F0D93D032CCAF37E7FE20A8B419</value>
<value>CN=Microsoft Root Authority, OU=Microsoft Corporation, OU=Copyright (c) 1997 Microsoft Corp.</value>
</row>
</data>
我需要能够将具有这种结构的数据解析到 SQL 表中,以便将来能够使用它。预期的结果是 SQL 表,看起来像这样:
DeviceID VolumeName SizeGB FreeSpaceGB FreeSpacePercent
-------- --------------- ------ ----------- ----------------
C: c$OS-COMPUTER01 126 43 34
D: D$DB-COMPUTER01 127 104 82
E: E$COMPUTER01 127 106 84
目前我将头数据和行数据解析到临时表中,并遍历各个表构建动态 SQL 代码,然后执行它以创建另一个表并将解析后的数据插入其中。
--code snippet which parses the rows
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) n, xx.value('.', 'VARCHAR(MAX)') v INTO #rows
FROM (values(@x)) t1(x)
CROSS APPLY x.nodes('//row/value') t2(xx)
...
--code snippet building the INSERT queries
WHILE (@loopcounter * @columns) < @rows
BEGIN
DECLARE @insertstatement VARCHAR(MAX)
SET @insertstatement = 'INSERT INTO #result VALUES ('
DECLARE @forcounter INT = 1
WHILE @forcounter <= @columns
BEGIN
DECLARE @rownumber int = (@loopcounter * @columns) + @forcounter
SELECT @insertstatement += '''' + REPLACE(v, '''', '''''') + ''', ' FROM #rows WHERE n = @rownumber
SET @forcounter += 1
END
SET @insertstatement = SUBSTRING(@insertstatement, 1, LEN(@insertstatement) - 1)
SET @insertstatement += ')'
EXEC (@insertstatement)
SET @loopcounter += 1
END
...
我搜索了这个论坛,但没有找到解决方案,该解决方案可以动态处理以这种方式存储的列名。您能告诉我可以做什么吗?
【问题讨论】:
标签: xml tsql sql-server-2012 xml-parsing xquery