[英]XML Document to SQL Server Query
How to get data from XML file to SQL query, following code is not working.如何从 XML 文件获取数据到 SQL 查询,以下代码不起作用。
<FVDL>
<EngineData>
<RuleInfo>
<Rule id="13EFF385-69A9-494A-9C67-951FEDAB25ED">
<MetaInfo>
<Group name="package">Python Core xml</Group>
<Group name="inputsource">XML Document</Group>
<Group name="audience">broad</Group>
</MetaInfo>
</Rule>
<Rule id="E9DB1C0E-025E-4EBF-A804-6C3DA413E652">
<MetaInfo>
<Group name="altcategoryMIS">Python Core zipfile</Group>
<Group name="altcategoryGDPR">Access Violation</Group>
</MetaInfo>
</Rule>
</RuleInfo>
</EngineData>
</FVDL>
USE OPENXMLTesting
GO
DECLARE @XML AS XML, @hDoc AS INT
SELECT @XML = XMLData FROM XMLwithOpenXML
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
Select ID, name, [Group]
FROM OPENXML(@hDoc, 'FVDL/EngineData/RuleInfo')
WITH
(
ID [varchar](100) 'Rule/@id',
[name] [varchar](100) 'Rule/MetaInfo/Group/@name',
[Group] [varchar](1000) 'MetaInfo/Group/.. '
)
EXEC sp_xml_removedocument @hDoc
Looking for result like this寻找这样的结果
ID ![]() |
Name![]() |
Group![]() |
---|---|---|
13EFF385-69A9-494A-9C67-951FEDAB25ED ![]() |
package![]() |
Python Core xml ![]() |
13EFF385-69A9-494A-9C67-951FEDAB25ED ![]() |
nputsource![]() |
XML Document ![]() |
13EFF385-69A9-494A-9C67-951FEDAB25ED ![]() |
audience![]() |
broad![]() |
E9DB1C0E-025E-4EBF-A804-6C3DA413E652 ![]() |
altcategoryMIS![]() |
Python Core zipfile ![]() |
E9DB1C0E-025E-4EBF-A804-6C3DA413E652 ![]() |
altcategoryGDPR![]() |
Access Violation![]() |
Please try the following solution.请尝试以下解决方案。
Starting from SQL Server 2005 onwards, it is better to use XQuery language, based on the w3c standards, while dealing with the XML data type.从 SQL Server 2005 开始,在处理 XML 数据类型时,最好使用基于 w3c 标准的 XQuery 语言。
Microsoft proprietary OPENXML
and its companions sp_xml_preparedocument
and sp_xml_removedocument
are kept just for backward compatibility with the obsolete SQL Server 2000. Their use is diminished just to very few fringe cases.保留 Microsoft 专有的
OPENXML
及其伙伴sp_xml_preparedocument
和sp_xml_removedocument
只是为了与过时的 SQL Server 2000 向后兼容。它们的使用减少到很少的边缘情况。 It is strongly recommended to re-write your SQL and switch it to XQuery.强烈建议重新编写您的 SQL 并将其切换到 XQuery。
SQL SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<FVDL>
<EngineData>
<RuleInfo>
<Rule id="13EFF385-69A9-494A-9C67-951FEDAB25ED">
<MetaInfo>
<Group name="package">Python Core xml</Group>
<Group name="inputsource">XML Document</Group>
<Group name="audience">broad</Group>
</MetaInfo>
</Rule>
<Rule id="E9DB1C0E-025E-4EBF-A804-6C3DA413E652">
<MetaInfo>
<Group name="altcategoryMIS">Python Core zipfile</Group>
<Group name="altcategoryGDPR">Access Violation</Group>
</MetaInfo>
</Rule>
</RuleInfo>
</EngineData>
</FVDL>');
-- DDL and sample data population, end
SELECT p.value('@id', 'UNIQUEIDENTIFIER') AS ID
, c.value('@name', 'VARCHAR(30)')AS [Name]
, c.value('(./text())[1]', 'VARCHAR(30)')AS [Group]
FROM @tbl
CROSS APPLY xmldata.nodes('/FVDL/EngineData/RuleInfo/Rule') AS t1(p)
CROSS APPLY t1.p.nodes('MetaInfo/Group') AS t2(c);
Output输出
+--------------------------------+-----------------+---------------------+
| ID | Name | Group |
+--------------------------------+-----------------+---------------------+
| 13EFF385-69A9-494A-9C67-951FED | package | Python Core xml |
| 13EFF385-69A9-494A-9C67-951FED | inputsource | XML Document |
| 13EFF385-69A9-494A-9C67-951FED | audience | broad |
| E9DB1C0E-025E-4EBF-A804-6C3DA4 | altcategoryMIS | Python Core zipfile |
| E9DB1C0E-025E-4EBF-A804-6C3DA4 | altcategoryGDPR | Access Violation |
+--------------------------------+-----------------+---------------------+
OPENXML is a bit wonky and is outdated. OPENXML 有点不稳定并且已经过时了。 If you need to use it, you need to provide the path down to
<Group>
and then work your way back up to the other elements.如果您需要使用它,您需要提供到
<Group>
的路径,然后再回到其他元素。 This should do it for you based on your sample XML.这应该根据您的示例 XML 为您完成。
DECLARE @XML XML = N'<FVDL>
<EngineData>
<RuleInfo>
<Rule id="13EFF385-69A9-494A-9C67-951FEDAB25ED">
<MetaInfo>
<Group name="package">Python Core xml</Group>
<Group name="inputsource">XML Document</Group>
<Group name="audience">broad</Group>
</MetaInfo>
</Rule>
<Rule id="E9DB1C0E-025E-4EBF-A804-6C3DA413E652">
<MetaInfo>
<Group name="altcategoryMIS">Python Core zipfile</Group>
<Group name="altcategoryGDPR">Access Violation</Group>
</MetaInfo>
</Rule>
</RuleInfo>
</EngineData>
</FVDL>'
DECLARE @hDoc AS INT
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
Select ID, name, [Group]
FROM OPENXML(@hDoc, 'FVDL/EngineData/RuleInfo/Rule/MetaInfo/Group')
WITH
(
id [varchar](100) '../../@id',
[name] [varchar](100) '@name',
[Group] [varchar](1000) '.'
)
EXEC sp_xml_removedocument @hDoc
I strongly suggest you don't use OPENXML
, as it has many issues.我强烈建议您不要使用
OPENXML
,因为它有很多问题。
Instead use the newer XQuery functions, which are far simpler to use而是使用较新的 XQuery 函数,它们使用起来要简单得多
.nodes
feeds into the next..nodes
如何馈入下一个。 This is only necessary because there are two separate levels of nodes that need breaking into separate rows.SELECT
ID = rl.value('@id','uniqueidentifier'),
[name] = grp.value('@name', 'varchar(100)'),
[Group] = grp.value('text()[1]','varchar(1000)')
FROM XMLwithOpenXML
CROSS APPLY XMLData.nodes('FVDL/EngineData/RuleInfo/Rule') x1(rl)
CROSS APPLY x1.rl.nodes('MetaInfo/Group') x2(Grp);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.