【问题标题】:Method for importing System.Data.Dataset XML file into SQL Server using T-SQL使用 T-SQL 将 System.Data.Dataset XML 文件导入 SQL Server 的方法
【发布时间】:2021-10-14 11:33:19
【问题描述】:

背景:我正在更新 PowerShell 中的脚本,这些脚本会定期将大量数据从非 MS 数据库导出到不同主机上的 SQL Server。

在导出方面,我选择了 .NET System.Data.Dataset 对象作为数据格式。传输文件是使用带有WriteSchema 选项的WriteXml 方法创建的。这种方法支持多个表,并将接收服务器的数据库模式信息保留在一个文件中。

根据请求,一个基本的DataSet 文件可能是:

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="table1">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="col1" type="xs:string" minOccurs="0" />
                <xs:element name="col2" type="xs:string" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
          <xs:element name="table2">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="col1" type="xs:string" minOccurs="0" />
                <xs:element name="col2" type="xs:string" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <table1>
    <col1>tkshrq</col1>
    <col2>6krrtq</col2>
  </table1>
  <table1>
    <col1>k60stu</col1>
    <col2>sqnhp9</col2>
  </table1>
  <table2>
    <col1>6k1thw</col1>
    <col2>n2ocgz</col2>
  </table2>
  <table2>
    <col1>26kmw5</col1>
    <col2>ym3iwd</col2>
  </table2>
</NewDataSet>

在接收端,我有一个导入脚本,它利用Write-SqlTableData 将表从DataSet 文件批量加载到临时表中,然后运行存储过程以在数据移动到“实时”表时提供事务隔离.

我希望找到一种从 T-SQL 中直接访问 DataSet 文件的方法,以便可以通过单个存储过程完成导入。

我知道如何为平面“行集”文件(CSV、DataTable 等)设置链接服务器并使用OPENROWSET 查询它们。但是我没有成功访问多表DataSet文件。

我对更改传输文件格式不感兴趣。它有几个理想的功能,我宁愿处理大量的临时表,也不愿处理大量的传输文件。

我还知道 SQL Server 的第三方 XML ODBC 提供程序。但在这种情况下不允许使用第三方软件。

【问题讨论】:

  • 请提供您的数据集 XML 文件的最小示例。

标签: sql-server dataset


【解决方案1】:

请尝试以下解决方案。

它正在使用 T-SQL 和 XQuery 方法 .nodes().value()

我将您的 XML 保存为 'e:\Temp\NewDataSet.xml' 文件。

SQL Server XML 数据类型最多可容纳 2GB 大小。

如果建议方法的性能不是那么好,根据数据量,可以将整个 XML 文件加载到一个一行一列的临时表中。

SQL

DECLARE @tbl1 TABLE (ID INT IDENTITY PRIMARY KEY,  col1 VARCHAR(50), col2 VARCHAR(50));
DECLARE @tbl2 TABLE (ID INT IDENTITY PRIMARY KEY,  col1 VARCHAR(50), col2 VARCHAR(50));

DECLARE @xml XML;

SELECT @xml = XmlDoc   
FROM OPENROWSET (BULK N'e:\Temp\NewDataSet.xml', SINGLE_BLOB, CODEPAGE='65001') AS Tab(XmlDoc);

INSERT INTO @tbl1 (col1, col2)
SELECT c.value('(col1/text())[1]', 'VARCHAR(50)') AS col1
   , c.value('(col2/text())[1]','VARCHAR(50)') AS col2
FROM @xml.nodes('/NewDataSet/table1') AS t(c);

INSERT INTO @tbl2 (col1, col2)
SELECT c.value('(col1/text())[1]', 'VARCHAR(50)') AS col1
   , c.value('(col2/text())[1]','VARCHAR(50)') AS col2
FROM @xml.nodes('/NewDataSet/table2') AS t(c);

-- test
SELECT * FROM @tbl1;
SELECT * FROM @tbl2;

输出

表1

+----+--------+--------+
| ID |  col1  |  col2  |
+----+--------+--------+
|  1 | tkshrq | 6krrtq |
|  2 | k60stu | sqnhp9 |
+----+--------+--------+

表2

+----+--------+--------+
| ID |  col1  |  col2  |
+----+--------+--------+
|  1 | 6k1thw | n2ocgz |
|  2 | 26kmw5 | ym3iwd |
+----+--------+--------+

【讨论】:

  • 很好,@Yitzhak!我会玩这个,让你知道。 -谢谢
  • 谢谢,伊扎克。如所问,这是一个很好的解决方案,所以我接受了。但是,出于我的目的,我不能使用它。我需要一个解决方案,该解决方案将从DataSet 对象以及数据导入架构,并希望有一些方法可以建立到DataSet 文件的链接服务器,以便在查询中隐含列类型。我很困惑,因为这两个都是 MS 域,我找不到关于如何执行这个明显任务的文档。
  • @Frobozz,作为替代解决方案,可以从 &lt;xs:schema&gt; 片段动态生成 INSERT 语句作为动态 SQL。
  • 如果它可以被包装在一个事务中并适应源模式的变化(这将会发生),我对你能提供的任何例子都非常感兴趣。
  • @Frobozz,请将其作为一个单独的新问题提出。
猜你喜欢
  • 1970-01-01
  • 2013-10-18
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 2023-03-04
  • 2013-05-26
  • 2023-03-16
  • 2016-10-29
相关资源
最近更新 更多