我有以下查询返回以下XML结果集。
请注意查询1结果中的嵌套<Configuration>
元素。
问题:
如果我添加一个case语句,它会从xml输出中删除列名。这给了我预期的结果。如果没有case语句或嵌套select,我怎么能这样做呢? 请参阅查询2&amp;查询2结果示例。
查询1:
SELECT
(SELECT
q.NotificationQueueId
,nc.Configuration -- Provides unexpected result -- Nested <Configuration><Configuration /></Configuration>
,q.UserAdded
,q.DateAdded
,q.UserEdited
,q.DateEdited
,q.IsActive
FROM Queue q
INNER JOIN NotificationConfigurations nc ON nc.NotificationConfigurationId = q.NotificationConfigurationId
FOR XML RAW ('NotificationItem'),TYPE)
FOR XML RAW ('NotificationItems'),TYPE
查询1结果:
<NotificationItems>
<NotificationItem NotificationQueueId="1" UserAdded="someone" DateAdded="2016-02-29T13:26:11.110" IsActive="1">
<Configuration>
<Configuration>
<Email AddressList="blah@blah.com" Subject="blah blah blah">
</Email>
</Configuration>
</Configuration>
</NotificationItem>
</NotificationItems>
查询2:
SELECT
(SELECT
q.NotificationQueueId
,CASE WHEN 1 = 1 THEN nc.Configuration END -- Provides expected result
,(SELECT nc.Configuration) -- Provides expected result
,q.UserAdded
,q.DateAdded
,q.UserEdited
,q.DateEdited
,q.IsActive
FROM Queue q
INNER JOIN NotificationConfigurations nc ON nc.NotificationConfigurationId = q.NotificationConfigurationId
FOR XML RAW ('NotificationItem'),TYPE)
FOR XML RAW ('NotificationItems'),TYPE
查询2结果
<NotificationItems>
<NotificationItem NotificationQueueId="1" UserAdded="someone" DateAdded="2016-02-29T13:26:11.110" IsActive="1">
<Configuration>
<Email AddressList="blah@blah.com" Subject="blah blah blah">
</Email>
</Configuration>
</NotificationItem>
</NotificationItems>
表格定义:
CREATE TABLE [dbo].[NotificationConfigurations](
[NotificationConfigurationId] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[Configuration] [xml] NOT NULL,
)
CREATE TABLE [dbo].[Queue](
[NotificationQueueId] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[NotificationConfigurationId] [uniqueidentifier] NOT NULL,
[UserAdded] [nvarchar](128) NOT NULL,
[DateAdded] [datetime] NOT NULL,
[UserEdited] [nvarchar](128) NULL,
[DateEdited] [datetime] NULL,
[IsActive] [bit] NOT NULL,
)
示例配置Xml:
<Configuration>
<Email AddressList="blah@blah.com"
Subject="blah blah blah">
</Email>
</Configuration>
答案 0 :(得分:1)
请参阅示例:
WITH t1 AS (
SELECT 1 AS ID UNION SELECT 2
), t2 AS (
SELECT 1 AS ID, CONVERT(XML, '
<Configuration>
<Email AddressList="blah@blah.com" Subject="blah blah blah">
</Email>
</Configuration>
') As Configuration
)
SELECT (
SELECT t1.ID,
t2.Configuration,
CASE WHEN 1 = 1 THEN t2.Configuration END,
(SELECT nc.Configuration)
FROM t1
INNER JOIN t2 On t1.ID = t2.ID
FOR XML RAW ('NotificationItem'),TYPE
) FOR XML RAW ('NotificationItems'),TYPE
您的Configuration
字段已经是带有<Configuration />
根标记的XML。选中后,它将被包含在字段名称后面的额外<Configuration />
标记中。
您已经通过(SELECT nc.Configuration)
获得了解决方案,这导致“匿名”字段“按原样”包含在结果XML中,没有字段名称换行标记。而这个“嵌套查询”实际上并没有花费任何成本。
更新:原因Configuration
XML可以在JOIN
之前明确“解包”,但效率会低得多:
WITH t1 AS (
SELECT 1 AS ID UNION SELECT 2
), t2 AS (
SELECT 1 AS ID, CONVERT(XML, '
<Configuration>
<Email AddressList="blah@blah.com" Subject="blah blah blah">
</Email>
</Configuration>
') As Configuration
)
SELECT (
SELECT t1.ID,
t2sub.Configuration
FROM t1
INNER JOIN (
SELECT ID, sub.ConfigurationContents.query('.') AS Configuration
FROM t2
CROSS APPLY Configuration.nodes('/Configuration/child::node()') AS sub(ConfigurationContents)
) t2sub ON t2sub.id = t1.id
FOR XML RAW ('NotificationItem'),TYPE
) FOR XML RAW ('NotificationItems'),TYPE