Разбиение запроса SQL FOR XML на родительские элементы со специальными именами - PullRequest
1 голос
/ 08 апреля 2011

То, что я пытаюсь сделать, я думаю, довольно просто, поэтому, если вы знакомы с FOR XML в SQL Server, я бы рекомендовал перейти к нижней части и прочитать полужирный текст :)

Я пытаюсь использовать оператор FOR XML в SQL Server 2005 для достижения нужных мне результатов. В настоящее время у меня есть это ...

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 взяты из одной таблицы, хотя они являются отдельными элементами в этом запросе. (Вероятно, случай плохого дизайна) Но - то, что я хочу, достаточно просто, чтобы поместить родительский элемент вокруг элементов Reason и PulledSupportReason например ...

<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 PATH или XML EXPLICIT? Спасибо за любую помощь:)

1 Ответ

2 голосов
/ 08 апреля 2011

Попробуйте использовать 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-тега, равного определенному псевдониму.

...