【问题标题】:Import XML into SQL Server table将 XML 导入 SQL Server 表
【发布时间】:2018-05-06 00:01:04
【问题描述】:

我想将 xml 文件导入到平面表中。源文件的格式有点不寻常

<?xml version="1.0" encoding="utf-8"?>
  <db xmlns:site="http://www.google.com">
    <params>
    <param name="parser_version" value="2"/>
    <param name="data_type" value="Events"/>
    <param name="created" value="2017-11-15T12:21:18"/>
    <param name="program_version" value="4.5.20.1092"/>
    </params>
  <tables>
    <table name="Events">
      <fields>
        <field name="UniqueID" type="Integer"/>
        <field name="ID" type="AutoInc"/>
        <field name="Date" type="Date"/>
        <field name="Time" type="Time"/>
        <field name="Code" type="Integer"/>
        <field name="UserID" type="Integer"/>
        <field name="UserGUID" type="String"/>
        <field name="ReaderID" type="Integer"/>
        <field name="Type" type="Integer"/>
        <field name="Modified" type="Boolean"/>
        <field name="ModifReason" type="String"/>
      </fields>
      <rows>
        <row>
          <f>3086647</f>
          <f>18091842</f>
          <f>2017-11-14</f>
          <f>21:32:10</f>
          <f>1</f>
          <f>202</f>
          <f>{ED53D55D-4B99-41F3-95BD-6945A989155C}</f>
          <f>803</f>
          <f>32</f>
          <f>null</f>
          <f>null</f>
        </row>
...


      </rows>
    </table>
  </tables>

我想这都是关于 xsd 格式的,或者我需要执行一些 xml 任务操作。目前在 SSIS XML 源(数据流任务)中,当我尝试生成 xsd 时,它为我提供了一个包含数据的“f”表,没有任何标记和字段枚举。

结果我想要一个包含所有 11 列的表。

【问题讨论】:

  • 请勿发图!编辑您的问题并提供一个(简化但有效的)XML 作为 copy-n-pasteable 文本。这个 XML 来自哪里?
  • @Shnugo 对不起图片,已更正

标签: sql-server xml ssis xsd


【解决方案1】:

我不知道这是否会对您有所帮助,但以下 T_SQL 方法会将您的 XML 扁平化为可导入的集合。您必须依赖 &lt;field&gt;&lt;f&gt; 元素的隐式排序,因为它们仅按位置匹配。

这应该适用于任何数量的表格和任何数量的行,只要表格的名称是唯一的

DECLARE @xml XML=
N'<db xmlns:site="http://www.google.com">
  <params>
    <param name="parser_version" value="2" />
    <param name="data_type" value="Events" />
    <param name="created" value="2017-11-15T12:21:18" />
    <param name="program_version" value="4.5.20.1092" />
  </params>
  <tables>
    <table name="Events">
      <fields>
        <field name="UniqueID" type="Integer" />
        <field name="ID" type="AutoInc" />
        <field name="Date" type="Date" />
        <field name="Time" type="Time" />
        <field name="Code" type="Integer" />
        <field name="UserID" type="Integer" />
        <field name="UserGUID" type="String" />
        <field name="ReaderID" type="Integer" />
        <field name="Type" type="Integer" />
        <field name="Modified" type="Boolean" />
        <field name="ModifReason" type="String" />
      </fields>
      <rows>
        <row>
          <f>3086647</f>
          <f>18091842</f>
          <f>2017-11-14</f>
          <f>21:32:10</f>
          <f>1</f>
          <f>202</f>
          <f>{ED53D55D-4B99-41F3-95BD-6945A989155C}</f>
          <f>803</f>
          <f>32</f>
          <f>null</f>
          <f>null</f>
        </row>
      </rows>
    </table>
  </tables>
</db>';

--我假设您的 XML 存在于声明的变量 @xml

WITH AllTablesAndFields AS
(
    SELECT DENSE_RANK() OVER(ORDER BY tbl.value('@name','nvarchar(max)')) AS TableInx
          ,tbl.value('@name','nvarchar(max)') AS TableName
          ,ROW_NUMBER() OVER(PARTITION BY tbl.value('@name','nvarchar(max)') ORDER BY (SELECT NULL)) AS FieldInx
          ,fld.value('@name','nvarchar(max)') AS FieldName
          ,fld.value('@type','nvarchar(max)') AS FieldType
    FROM @xml.nodes('/db/tables/table') AS A(tbl)
    OUTER APPLY tbl.nodes('fields/field') AS B(fld)
)
,AllTablesAndRows AS
(
    SELECT DENSE_RANK() OVER(ORDER BY tbl.value('@name','nvarchar(max)')) AS TableInx
          ,tbl.value('@name','nvarchar(max)') AS TableName
          ,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowInx
          ,rw.query('.') AS RowNode
    FROM @xml.nodes('/db/tables/table') AS A(tbl)
    OUTER APPLY tbl.nodes('rows/row') AS B(rw)
)
,AllValues AS
(
    SELECT rws.TableInx
          ,rws.TableName
          ,rws.RowInx
          ,ROW_NUMBER() OVER(PARTITION BY rws.RowInx ORDER BY (SELECT NULL)) AS ValueInx
          ,fld.value('text()[1]','nvarchar(max)') AS Val
    FROM AllTablesAndRows AS rws
    OUTER APPLY rws.RowNode.nodes('row/f') AS A(fld)
)

SELECT flds.TableName
      ,flds.FieldName
      ,flds.FieldType
      ,vals.Val
FROM AllValues AS vals
FULL OUTER JOIN AllTablesAndFields AS flds ON vals.TableInx=flds.TableInx AND vals.ValueInx=flds.FieldInx;

结果

+-----------+-------------+-----------+----------------------------------------+
| TableName | FieldName   | FieldType | Val                                    |
+-----------+-------------+-----------+----------------------------------------+
| Events    | UniqueID    | Integer   | 3086647                                |
+-----------+-------------+-----------+----------------------------------------+
| Events    | ID          | AutoInc   | 18091842                               |
+-----------+-------------+-----------+----------------------------------------+
| Events    | Date        | Date      | 2017-11-14                             |
+-----------+-------------+-----------+----------------------------------------+
| Events    | Time        | Time      | 21:32:10                               |
+-----------+-------------+-----------+----------------------------------------+
| Events    | Code        | Integer   | 1                                      |
+-----------+-------------+-----------+----------------------------------------+
| Events    | UserID      | Integer   | 202                                    |
+-----------+-------------+-----------+----------------------------------------+
| Events    | UserGUID    | String    | {ED53D55D-4B99-41F3-95BD-6945A989155C} |
+-----------+-------------+-----------+----------------------------------------+
| Events    | ReaderID    | Integer   | 803                                    |
+-----------+-------------+-----------+----------------------------------------+
| Events    | Type        | Integer   | 32                                     |
+-----------+-------------+-----------+----------------------------------------+
| Events    | Modified    | Boolean   | null                                   |
+-----------+-------------+-----------+----------------------------------------+
| Events    | ModifReason | String    | null                                   |
+-----------+-------------+-----------+----------------------------------------+

包括 TableInx、FieldInx、RowInx 和 ValueInx 以分隔您的结果

【讨论】:

    猜你喜欢
    • 2013-05-26
    • 2023-03-16
    • 1970-01-01
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    相关资源
    最近更新 更多