2016-03-01 50 views
0

我有以下查询返回以下XML结果集。 请注意查询1结果中嵌套的<Configuration>元素。选择不包含列别名的XML列

问:

如果我添加一个case语句,它会从XML输出列名。这给了我预期的结果。如何在没有case语句或嵌套select的情况下执行此操作?
查看查询2 &查询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="[email protected]" 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="[email protected]" 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="[email protected]" 
      Subject="blah blah blah"> 
    </Email> 
</Configuration> 
+0

我怀疑你有一些不寻常的输入数据。你能添加一些(基本的)表格定义和一些能产生这些结果的样本数据吗? –

+0

@Damien_The_Unbeliever:更新了表模式和示例配置。 –

+0

本例中'nc.Configuration'的原始值是多少? –

回答

1

请参见例如:

WITH t1 AS (
SELECT 1 AS ID UNION SELECT 2 
), t2 AS (
SELECT 1 AS ID, CONVERT(XML, ' 
    <Configuration> 
     <Email AddressList="[email protected]" 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="[email protected]" 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