2015-03-26 2 views
3

Объем этого проекта намного больше, чем этот вопрос. Мне поручили проект, и я не буду утомлять вас интимными подробностями. В конечном итоге то, что мне нужно сделать, это получить данные из базы данных и в XML, чтобы я мог конвертировать в JSON и создавать простое веб-приложение, которое позволит мне анализировать и форматировать данные так, чтобы они соответствовали потребностям клиента.Использование SQL FOR XML PATH, как я могу получить следующий отформатированный вывод XML?

Я уверен, что есть лучший способ сделать это, но это путь, я остановился на ..

У меня есть около 46000 записей сбрасывали в таблицу Temp. Чтобы дать вам представление о том, как эти данные структурированы, выполнив следующий запрос:

SELECT 
    TransactionID, 
    OwnerID, 
    Date, 
    TransactionType, 
    ChargeCode, 
    Description, 
    DebitAmount 
FROM #OwnerHistoryTemp 
WHERE OwnerID = '11111111' 

возвращает это:

TransactionID OwnerID  Date  TransactionType ChargeCode Description   DebitAmount 
28727   11111111 2014-12-01 E    A1   APPLY CHARGES  210.00 
28728   11111111 2014-12-03 C    A1   DB11111111   210.00 
28729   11111111 2015-01-01 E    A1   APPLY CHARGES  183.37 

Что я ищу здесь сделать, это использовать SQL FOR XML PATH (открытый для любых других предложений) для вывода данных, как так:

<OwnerHistory> 
    <OwnerID OwnerID="11111111"> 
     <Transactions> 
      <TransactionID ID="28727"> 
       <Date>2014-12-01</Date> 
       <TransactionType>E</TransactionType> 
       <ChargeCode>A1</ChargeCode> 
       <Description>APPLY CHARGES</Description> 
       <DebitAmount>210.00</DebitAmount> 
      </TransactionID> 
      <TransactionID ID="28728"> 
       <Date>2014-12-03</Date> 
       <TransactionType>C</TransactionType> 
       <ChargeCode>A1</ChargeCode> 
       <Description>DB11111111</Description> 
       <DebitAmount>210.00</DebitAmount> 
      </TransactionID> 
      <TransactionID ID="28729"> 
       <Date>2015-1-01</Date> 
       <TransactionType>E</TransactionType> 
       <ChargeCode>A1</ChargeCode> 
       <Description>APPLY CHARGES</Description> 
       <DebitAmount>183.37</DebitAmount> 
      </TransactionID> 
     </Transactions> 
    </OwnerID> 
</OwnerHistory> 

запросов меня, заставляет меня близко, но не совсем там. Поскольку же OwnerId появляется несколько раз (один раз для каждого TransactionID), выполнив следующий запрос:

SELECT 
    OwnerID AS "@OwnerID", 
    TransactionID AS "Transaction/@RecordID", 
    Date AS "Transaction/Date", 
    TransactionType AS "Transaction/TransactionType", 
    ChargeCode AS "Transaction/ChargeCode", 
    Description AS "Transaction/Description", 
    DebitAmount AS "Transaction/DebitAmount" 
FROM #OwnerHistoryTemp 
WHERE OwnerID = '11111111' 
GROUP BY OwnerID, RecordID, Date, ChargeCode, Description, DebitAmount 
order by OwnerID 
FOR XML PATH ('OwnerID'), ROOT('OwnerHistory') 

Возвращает на следующие:

<OwnerHistory> 
    <OwnerID OwnerID="11111111"> 
     <Transaction RecordID="28727"> 
      <Date>2014-12-01</Date> 
      <TransactionType>E</TransactionType> 
      <ChargeCode>A1</ChargeCode> 
      <Description>APPLY CHARGES</Description> 
      <DebitAmount>210.0000</DebitAmount> 
     </Transaction> 
    </OwnerID> 
    <OwnerID OwnerID="11111111"> 
     <Transaction RecordID="28728"> 
      <Date>2014-12-03</Date> 
      <TransactionType>C</TransactionType> 
      <ChargeCode>A1</ChargeCode> 
      <Description>DB11111111</Description> 
      <DebitAmount>210.0000</DebitAmount> 
     </Transaction> 
    </OwnerID> 
    <OwnerID OwnerID="11111111"> 
     <Transaction RecordID="28729"> 
      <Date>2015-01-01</Date> 
      <TransactionType>E</TransactionType> 
      <ChargeCode>A1</ChargeCode> 
      <Description>APPLY CHARGES</Description> 
      <DebitAmount>183.3700</DebitAmount> 
     </Transaction> 
    </OwnerID> 
</OwnerHistory> 

Любые мысли о том, как только тянуть OwnerId один раз, как Родительский и группировать все транзакции под ним?

Может быть, что-то просто, я просто не понимаю, или это может быть невозможно. Не стесняйтесь публично тронуть меня, если это первый случай ...

ответ

3

Готов к использованию?

Nest ваши запросы, чтобы получить вложенные XML, что-то вроде этого:

SELECT TOP 1 
    OwnerID AS "@ID", 
    (SELECT 
     TransactionID AS "Transaction/@ID", 
     [Date] AS "Transaction/Date", 
     TransactionType AS "Transaction/Type", 
     ChargeCode AS "Transaction/ChargeCode", 
     [Description] AS "Transaction/Description", 
     DebitAmount AS "Transaction/DebitAmount" 
    FROM OwnerHistory 
    WHERE OwnerID = [Owner].OwnerID 
    FOR XML PATH(''), TYPE) Transactions 
FROM OwnerHistory [Owner] 
WHERE OwnerID = '11111111' 
FOR XML PATH('Owner'), ROOT('OwnerHistory'), TYPE 

Результирующий XML:

<OwnerHistory> 
    <Owner ID="11111111"> 
    <Transactions> 
     <Transaction ID="28727"> 
     <Date>2015-03-26</Date> 
     <Type>E</Type> 
     <ChargeCode>A1</ChargeCode> 
     <Description>APPLY CHARGES</Description> 
     <DebitAmount>210.0000</DebitAmount> 
     </Transaction> 
     <Transaction ID="28728"> 
     <Date>2015-03-26</Date> 
     <Type>C</Type> 
     <ChargeCode>A1</ChargeCode> 
     <Description>DB11111111</Description> 
     <DebitAmount>210.0000</DebitAmount> 
     </Transaction> 
     <Transaction ID="28729"> 
     <Date>2015-03-26</Date> 
     <Type>E</Type> 
     <ChargeCode>A1</ChargeCode> 
     <Description>APPLY CHARGES</Description> 
     <DebitAmount>183.3700</DebitAmount> 
     </Transaction> 
    </Transactions> 
    </Owner> 
</OwnerHistory> 

Обратите внимание, что TOP 1 включается только, чтобы избежать повторения весь набор операций для каждого строка, содержащая OwnerID. Это можно было бы обработать несколькими способами; обычно такого рода вложенность будет результатом объединения на двух нормализованных таблицах, так что произойдет только один экземпляр Owner.

В MSDN есть несколько хороших examples, чтобы продемонстрировать эту технику.

+0

Хмммммм ..... Я попытался запустить это и немного настроить его. Я также прочитал документацию. Я буду продолжать играть с ним и посмотреть, что я могу придумать. Спасибо за ваш ответ!! –

+0

@ FernandoVega, извините, я ответил на свой телефон без использования базы данных. Я обновил ответ с помощью проверенного запроса. – dartonw

+0

Эй, парень !! Это круто!! Я был так близок, но до сих пор: '( Я очень ценю, что вы нашли время, чтобы изучить это и понять это для меня. Не только это, но и воспитание меня! Я не уверен, где вы, но если вы когда-либо в MN, у вас есть по крайней мере 12 пачек пива, ожидающих вас! Черт, целый случай! FYI Я попытался поднять ваше решение, но это не позволило мне не иметь уровень репутации 15. Если/когда я это сделаю, я попробую и вернусь, чтобы дать вам несколько очков! Еще раз спасибо !!! –