1

我已经研究了广泛粉碎这个 xml 文件的最佳方法,并且已经接近但并非完全达到我想要的效果。

我正在使用 SQL Server 2012 并且也有 Visual Studio 2012,尽管我更喜欢使用 SQL Server。

这是我正在使用的 XML 数据类型的片段。我无法控制如何构建 XML,因为它来自第 3 方。在节点下方的现实中,大约有 450 种响应类型,例如 ResponseID、名称、状态等……我只显示了大约 10 种。

<xml>
    <Response>
        <ResponseID>R_a4yThVvKXzVyftz</ResponseID>
        <ResponseSet>Default Response Set</ResponseSet>
        <Name>Doe, John</Name>
        <ExternalDataReference>0</ExternalDataReference>
        <EmailAddress>jdoe@gmail.com</EmailAddress>
        <IPAddress>140.123.12.123</IPAddress>
        <Status>0</Status>
        <StartDate>2014-09-18 09:21:11</StartDate>
        <EndDate>2014-09-23 16:09:58</EndDate>
        <Finished>1</Finished>
            </Response>
</xml>

我已经尝试过此站点上显示的 OPENROWSET 方法

http://blogs.msdn.com/b/simonince/archive/2009/04/24/flattening-xml-data-in-sql-server.aspx

使用这样的查询:

SELECT
a1.value('(RESPONSEID/text())[1]', 'varchar(50)') as RESPONSEID,
a2.value('(RESPONSESET/text())[1]', 'varchar(50)') as RESPONSESET,
a3.value('(NAME/text())[1]', 'varchar(50)') as NAME
FROM  XmlSourceTable
CROSS APPLY XmlData.nodes('//Response') AS RESPONSEID(a1)
CROSS APPLY XmlData.nodes('//Response') AS RESPONSESET(a2)
CROSS APPLY XmlData.nodes('//Response') AS NAME(a3)

我得到了这个工作一次,但是粉碎的输出是重复值并且没有出现在我想要的表格形式中,就像下面的输出一样,但实际上请注意表格非常宽,总共至少 450 行。另一个问题是由于宽度大于 255,我无法将其转换为 .txt 并导入它,尽管我强烈希望使用和切碎本机 XML,以便此过程可以自动化:

RESPONSEID  RESPONSESET NAME    EXTERNALDATAREFERENCE   EMAILADDRESS    IPADDRESS   STATUS  STARTDATE   ENDDATE
R_a4yThVvKXzVyftz   Default Response Set    Doe, John   1/1/2014    doej@gmail.com  123.12.123  0   9/18/2014 9:21  9/23/2014 16:09
R_06znwEis73yLsnX   NonDefault Response Set Doe, Jane   1/1/2014    doeja@gmail.com 123.12.123  0   9/18/2014 5:29  9/29/2014 9:42
R_50HuB0jDFfI6hmZ   Response Set 1  Doe, Cindy  1/1/2014    doec@gmail.com  123.12.123  0   9/18/2014 17:21 10/1/2014 11:45

我确实找到了这个应用程序

https://www.novixys.com/ExultSQLServer/

粉碎为节点创建单个表的 XML 文件然而,除了响应表之外,它还为每个响应节点创建一个表,从而产生大约 500 个额外的表。此外,该应用程序的费用为 250 美元。

https://www.novixys.com/ExultSQLServer/

4

1 回答 1

1

您不需要为要提取的每个值添加交叉应用。一个就够了。

SELECT
  R.X.value('(ResponseID/text())[1]', 'varchar(50)') as RESPONSEID,
  R.X.value('(ResponseSet/text())[1]', 'varchar(50)') as RESPONSESET,
  R.X.value('(Name/text())[1]', 'varchar(50)') as NAME
FROM  XmlSourceTable
  CROSS APPLY XmlData.nodes('//Response') AS R(X)
于 2014-11-17T09:57:30.610 回答