使用 OPENXML() 是将 XML 列中的数据转换为行和列的最佳方式吗?
Is using OPENXML() the best way to transform data in an XML Column to Rows and Columns?
我有一个 SQL 服务器 table,其列类型为 XML
。 XML 数据表示给定字段的多个允许选择。 XML数据的示例如下。
<Values>
<Value>Valid Value 1</Value>
<Value>Valid Value 2</Value>
<Value>Valid Value 3</Value>
<Value>Valid Value 4</Value>
<Value>Valid Value 5</Value>
<Value>Valid Value 6</Value>
...
</Values>
我正在使用以下代码从 XML
列中提取数据并将其转换为可以插入到新 table.
中的行
DECLARE @XmlStuff VARCHAR(4000);
DECLARE @iXmlStuff int;
SELECT @XmlStuff = CAST(C.ValidValues AS VARCHAR(4000))
FROM dbo.ColumnValidations C
WHERE C.[ColumnName] = 'Something';
EXEC sp_xml_preparedocument @iXmlStuff OUTPUT, @XmlStuff;
SELECT *
FROM OPENXML(@iXmlStuff, '/Values/Value', 2)
WITH ([Value] VARCHAR(100) '.');
EXEC sp_xml_removedocument @iXmlStuff;
此代码正确返回以下内容
Value
----------------
Valid Value 1
Valid Value 2
Valid Value 3
Valid Value 4
Valid Value 5
Valid Value 6
...
这是最好的方法吗?
我认为我这里的内容需要存储在存储过程中。理想情况下,我正在寻找一种方法,这样我就不必担心由于 xml 列中包含的不可预见的数据量导致缓冲区溢出而丢失数据。
OPENXML()
及其同伴 sp_xml_preparedocument/sp_xml_removedocument
是专有的 Microsoft API。它只是为了落后而保留
与过时的 SQL Server 2000 兼容。SQL Server 2005 及更高版本支持 w3c 的 XQuery 1.0、XPath 2.0 和 XSD 1.0。
SQL
-- DDL and sample data population, start
DECLARE @tbl Table (ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<Values>
<Value>Valid Value 1</Value>
<Value>Valid Value 2</Value>
<Value>Valid Value 3</Value>
<Value>Valid Value 4</Value>
<Value>Valid Value 5</Value>
<Value>Valid Value 6</Value>
</Values>');
-- DDL and sample data population, end
SELECT ID
, c.value('.','VARCHAR(100)') AS Result
FROM @tbl CROSS APPLY xmldata.nodes('/Values/Value/text()') AS t(c);
输出
+----+---------------+
| ID | Result |
+----+---------------+
| 1 | Valid Value 1 |
| 1 | Valid Value 2 |
| 1 | Valid Value 3 |
| 1 | Valid Value 4 |
| 1 | Valid Value 5 |
| 1 | Valid Value 6 |
+----+---------------+
我有一个 SQL 服务器 table,其列类型为 XML
。 XML 数据表示给定字段的多个允许选择。 XML数据的示例如下。
<Values>
<Value>Valid Value 1</Value>
<Value>Valid Value 2</Value>
<Value>Valid Value 3</Value>
<Value>Valid Value 4</Value>
<Value>Valid Value 5</Value>
<Value>Valid Value 6</Value>
...
</Values>
我正在使用以下代码从 XML
列中提取数据并将其转换为可以插入到新 table.
DECLARE @XmlStuff VARCHAR(4000);
DECLARE @iXmlStuff int;
SELECT @XmlStuff = CAST(C.ValidValues AS VARCHAR(4000))
FROM dbo.ColumnValidations C
WHERE C.[ColumnName] = 'Something';
EXEC sp_xml_preparedocument @iXmlStuff OUTPUT, @XmlStuff;
SELECT *
FROM OPENXML(@iXmlStuff, '/Values/Value', 2)
WITH ([Value] VARCHAR(100) '.');
EXEC sp_xml_removedocument @iXmlStuff;
此代码正确返回以下内容
Value
----------------
Valid Value 1
Valid Value 2
Valid Value 3
Valid Value 4
Valid Value 5
Valid Value 6
...
这是最好的方法吗?
我认为我这里的内容需要存储在存储过程中。理想情况下,我正在寻找一种方法,这样我就不必担心由于 xml 列中包含的不可预见的数据量导致缓冲区溢出而丢失数据。
OPENXML()
及其同伴 sp_xml_preparedocument/sp_xml_removedocument
是专有的 Microsoft API。它只是为了落后而保留
与过时的 SQL Server 2000 兼容。SQL Server 2005 及更高版本支持 w3c 的 XQuery 1.0、XPath 2.0 和 XSD 1.0。
SQL
-- DDL and sample data population, start
DECLARE @tbl Table (ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<Values>
<Value>Valid Value 1</Value>
<Value>Valid Value 2</Value>
<Value>Valid Value 3</Value>
<Value>Valid Value 4</Value>
<Value>Valid Value 5</Value>
<Value>Valid Value 6</Value>
</Values>');
-- DDL and sample data population, end
SELECT ID
, c.value('.','VARCHAR(100)') AS Result
FROM @tbl CROSS APPLY xmldata.nodes('/Values/Value/text()') AS t(c);
输出
+----+---------------+
| ID | Result |
+----+---------------+
| 1 | Valid Value 1 |
| 1 | Valid Value 2 |
| 1 | Valid Value 3 |
| 1 | Valid Value 4 |
| 1 | Valid Value 5 |
| 1 | Valid Value 6 |
+----+---------------+