我收到了一些需要“分解”的 XML 数据(我认为这是正确的术语)。那就是我需要将它放入 SQL 表中。这是一个示例和一个有效的查询,但我被告知它效率低下。如果您知道更有效的方法,请告诉我。
下面是一些 XML 示例,其中 2 个查询不起作用,而一个则起作用:
DECLARE @XmlReportParameters NVARCHAR (MAX) = N'<?xml version="1.0" encoding="utf-16"?>
<Customers>
<Customer>
<Name>Sri Patel</Name>
<FavColors>
<FavColor>Red</FavColor>
<FavColor>Blue</FavColor>
<FavColor>Green</FavColor>
</FavColors>
</Customer>
<Customer>
<Name>Jane Doe</Name>
<FavColors>
<FavColor>Violet</FavColor>
<FavColor>Mauve</FavColor>
</FavColors>
</Customer>
</Customers>
'
DECLARE @doc XML;
DECLARE @XmlTable TABLE
(
XmlColumn XML NULL
);
SET @doc = @XmlReportParameters;
INSERT INTO @XmlTable
( XmlColumn )
VALUES
( @doc )
-- Wrong Way
SELECT
tbl.col.value('(Name)[1]', 'nvarchar(max)') AS CustomerName
,tbl.col.value('(FavColors/FavColor)[1]', 'nvarchar(max)') AS FavColor
FROM
@XmlTable xt
CROSS APPLY XmlColumn.nodes('/Customers/Customer') tbl(col);
-- Still wrong (but I'm not sure why)
SELECT
tbl.col.value('(../Name)[1]', 'nvarchar(max)') AS CustomerName
,tbl.col.value('(FavColor)[1]', 'nvarchar(max)') AS FavColor
FROM
@XmlTable xt
CROSS APPLY XmlColumn.nodes('/Customers/Customer/FavColors') tbl(col);
-- Right Way
SELECT
tbl.col.value('(../../Name)[1]', 'nvarchar(max)') AS CustomerName
,tbl.col.value('(.)[1]', 'nvarchar(max)') AS FavColor
FROM
@XmlTable xt
CROSS APPLY XmlColumn.nodes('/Customers/Customer/FavColors/FavColor') tbl(col);
返回:
CustomerName FavColor
------------ ----------
Sri Patel Red
Jane Doe Violet
CustomerName FavColor
------------ ----------
Sri Patel Red
Jane Doe Violet
CustomerName FavColor
------------ ----------
Sri Patel Red
Sri Patel Blue
Sri Patel Green
Jane Doe Violet
Jane Doe Mauve
最佳答案
这里的“低效率”是使用父轴来遍历备份文档以获取名称。执行此操作的首选方法是使用多个 APPLY 运算符。第一个将投影出 Customer 节点,然后第二个将投影出 FavColors 节点。像这样:
SELECT
CustomerNode.e.value('(Name)[1]', 'nvarchar(max)') AS CustomerName
,FavColorNode.e.value('(.)[1]', 'nvarchar(max)') AS FavColor
FROM
@XmlTable xt
CROSS APPLY XmlColumn.nodes('/Customers/Customer') CustomerNode(e)
CROSS APPLY CustomerNode.e.nodes('FavColors/FavColor') FavColorNode(e);
尽管对于大多数情况来说,它们之间的差异可能并不重要。
关于sql-server - 在 SQL Server 2014 中将 XML 数据转换为关系格式时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48950651/