【问题标题】:Breaking SQL FOR XML query into specifically named parent elements将 SQL FOR XML 查询分解为特定命名的父元素
【发布时间】:2011-04-08 13:42:20
【问题描述】:

我想做的事情我认为很简单,所以如果您熟悉 SQL Server 中的FOR XML,我建议您跳到底部并阅读 粗体文本部分: )

我正在尝试使用 SQL Server 2005 中的FOR XML 语句来实现我需要的结果。目前我有这个...

SELECT  
    txtReasonTypeID AS [ReasonTypeID]
  ,
    (SELECT 
    [Reason].intReasonID, 
    [Reason].txtReason
    FROM    CST_lnkProfileReason INNER JOIN 
    CST_tblReason AS [Reason] ON CST_lnkProfileReason.intReasonID = [Reason].intReasonID 
    WHERE   CST_lnkProfileReason.intProfileID = @intProfileID
    AND   CST_lnkProfileReason.txtReasonTypeID = [Response].txtReasonTypeID
    ORDER BY Reason.txtReason
    FOR XML AUTO, TYPE
    )
  ,
    (SELECT 
    [PulledSupportReason].intReasonID, 
    [PulledSupportReason].txtReason
    FROM    CST_lnkPulledSupportReason INNER JOIN 
    CST_tblReason AS [PulledSupportReason] ON CST_lnkPulledSupportReason.intReasonID = [PulledSupportReason].intReasonID 
    WHERE   CST_lnkPulledSupportReason.intProfileID = @intProfileID
    AND   CST_lnkPulledSupportReason.txtReasonTypeID = [Response].txtReasonTypeID
    ORDER BY [PulledSupportReason].txtReason
    FOR XML AUTO, TYPE
    )
FROM    CST_tblReasonTypes AS [Response]
FOR XML AUTO, ROOT('ResponseProfile')

正在返回以下 XML...

<ResponseProfile>
  <Response ReasonTypeID="ExampleType">
    <Reason intReasonID="106" txtReason="Call Back - 1"/>
    <Reason intReasonID="147" txtReason="Call Back - 2"/>
    <PulledSupportReason intReasonID="892" txtReason="PS Reason a"/>
    <PulledSupportReason intReasonID="893" txtReason="PS Reason b"/>
  </Response>
   ...more <Response>s
</ResponseProfile>

如您所见,Reason 元素和PulledSupportReason 元素来自同一个表,尽管它们在此查询中是单独的元素。 (可能是一个糟糕的设计案例)但是 - 我想要的很简单,在 ReasonPulledSupportReason 元素周围放置一个父元素 例如...

<ResponseProfile>
  <Response ReasonTypeID="ExampleType">
     <Reasons>
        <Reason intReasonID="106" txtReason="Call Back - 1"/>
        <Reason intReasonID="147" txtReason="Call Back - 2"/>
     </Reasons>
     <PulledSupportReasons>  
        <PulledSupportReason intReasonID="892" txtReason="PS Reason a"/>
        <PulledSupportReason intReasonID="893" txtReason="PS Reason b"/>
     </PulledSupportReasons>
  </Response>
   ...more <Response>s
</ResponseProfile>

我想我可以使用XML PATHXML EXPLICIT 来实现这一点?感谢您的帮助:)

【问题讨论】:

    标签: xml sql-server-2005 xsd for-xml


    【解决方案1】:

    尝试使用FOR XML PATH('....'), ROOT('....') - 有了它,你应该能够实现你想要的。

    我正在为第二个子选择说明这一点 - 为第一个子选择相应地调整:

    (SELECT 
        [PulledSupportReason].intReasonID, 
        [PulledSupportReason].txtReason
     FROM    
         CST_lnkPulledSupportReason 
     INNER JOIN 
        CST_tblReason AS [PulledSupportReason] ON CST_lnkPulledSupportReason.intReasonID = [PulledSupportReason].intReasonID 
     WHERE   
         CST_lnkPulledSupportReason.intProfileID = @intProfileID
         AND CST_lnkPulledSupportReason.txtReasonTypeID = [Response].txtReasonTypeID
     ORDER BY 
         [PulledSupportReason].txtReason
     FOR XML PATH('PulledSupportReason'), TYPE
    ) AS 'PulledSupportReasons'
    

    这应该可行,我希望! (不能真正测试,因为我手边没有你的桌子可以看)

    内部的FOR XML PATH(PulledSupportReason') 定义要使用的最里面的 XML 标记,为整个子选择 (AS 'PulledSupportReasons') 添加一个别名会为该子选择提供一个与定义的别名相等的包装 XML 标记。

    【讨论】:

    • 我知道这很容易!先生,您是一个该死的伟大传奇!但是,我只需要在每个SELECT 之后添加AS 'PulledSupportReasons' 等部分。我不需要使用XML PATH - 这样做的效果是我想要plus 将每个PulledSupportReason 行包含在&lt;PulledSupportReasons&gt; 标记中。希望你关注我!谢谢:D
    • 另外 - XML PATH 选项具有将行属性(例如 intReasonIDtxtReason)分解为单独元素(例如 &lt;intReasonID&gt;106&lt;\intReasonID&gt;)的效果。仍在努力了解这个FOR XML 业务!
    • @El Ronnoco:如果您希望在FOR XML PATH 中选择某项作为属性,请添加以@ 开头的列别名:SELECT PulledSupportReason.intReasonID AS '@ReasonID'
    • 谢谢,你是最棒的! :D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 2014-01-27
    • 2021-12-29
    相关资源
    最近更新 更多