将XML文件粉碎成SQL Server表

时间:2014-11-17 06:27:53

标签: sql-server xml shred

我已经研究过广泛粉碎这个xml文件的最佳方法,并且已经接近但不是一直到我想要的。

虽然我更喜欢使用SQL Server,但我正在使用SQL Server 2012并拥有Visual Studio 2012。

以下是我正在使用的XML数据类型的片段。我无法控制XML的构建方式,因为它来自第三方。在节点下面的Reality中,有大约450种响应类型,例如ResponseID,Name,Status等......我只显示大约十种。

<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文件粉碎了XML文件,它为每个响应节点创建了一个表,从而产生了大约500个额外的表。此外,该应用程序的成本为250美元..

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

1 个答案:

答案 0 :(得分: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)