使用 T-SQL 将 System.Data.Dataset XML 文件导入 SQL 服务器的方法
Method for importing System.Data.Dataset XML file into SQL Server using T-SQL
背景:我正在更新 PowerShell 中的脚本,这些脚本通常将大量数据从非 MS 数据库导出到不同主机上的 SQL 服务器。
在导出方面,我选择了 .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
文件。
我对更改传输文件格式不感兴趣。它有几个需要的功能,我宁愿处理无数的临时表,也不愿处理无数的传输文件。
我还知道 XML 服务器的第三方 XML ODBC 提供商。但是在这种情况下不允许使用第三方软件。
请尝试以下解决方案。
它正在使用 T-SQL 和 XQuery 方法 .nodes()
和 .value()
.
我将你的 XML 保存为 'e:\Temp\NewDataSet.xml' 文件。
SQL 服务器 XML 数据类型最多可容纳 2GB 大小。
如果建议的方法的性能不是很好,根据数据量,可以将整个 XML 文件加载到一个临时的 table 行中,并且一栏。
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 |
+----+--------+--------+
背景:我正在更新 PowerShell 中的脚本,这些脚本通常将大量数据从非 MS 数据库导出到不同主机上的 SQL 服务器。
在导出方面,我选择了 .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
文件。
我对更改传输文件格式不感兴趣。它有几个需要的功能,我宁愿处理无数的临时表,也不愿处理无数的传输文件。
我还知道 XML 服务器的第三方 XML ODBC 提供商。但是在这种情况下不允许使用第三方软件。
请尝试以下解决方案。
它正在使用 T-SQL 和 XQuery 方法 .nodes()
和 .value()
.
我将你的 XML 保存为 'e:\Temp\NewDataSet.xml' 文件。
SQL 服务器 XML 数据类型最多可容纳 2GB 大小。
如果建议的方法的性能不是很好,根据数据量,可以将整个 XML 文件加载到一个临时的 table 行中,并且一栏。
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 |
+----+--------+--------+