Skip to content
Advertisement

Loop through XML using SQL

I have this XML in a column in a MSSQL table

<QueryXMLData>
  <main ShowAllPhoneNumbers="yes">
    <C ID="5753768" HID="1" Name="Michael" SSN="xxxxxxxxxxx" PayType="" Status="Active" StatusID="1">
      <S ID="5483911" HID="3" Name="Ethan" SSN="xxxxxxxxxxx" CType="Subscription" TPID="21456" TPName="Outside" TPShortName="Out" Status="Active" StatusID="P" D="Y" Checked="yes" Found="yes">
        <TPIDs>
          <Phone TP="1122334455" />
        </TPIDs>
      </S>
    </C>
    <C ID="5670554" HID="1" Name="Susan" SSN="xxxxxxxxxxx" PayType="" Status="Active" StatusID="1">
      <S ID="5297452" HID="3" Name="Johnathan" SSN="xxxxxxxxxxx" CType="Outbound" TPID="110" TPName="Out" TPShortName="Inside" Status="Active" StatusID="1" D="Y" Checked="yes" Found="yes">
        <TPIDs>
          <Phone TP="3344556677" />
        </TPIDs>
      </S>
      <S ID="5297426" HID="3" Name="Brad" SSN="xxxxxxxxxxx" CType="Outbound" TPID="110" TPName="Out" TPShortName="Inside" Status="Active" StatusID="1" D="Y" Checked="yes" Found="yes">
        <TPIDs>
          <Phone TP="5566778899" />
        </TPIDs>
      </S>
    </C>
  </main>
</QueryXMLData>

I would like for it to return these columns:

Customer Name     Subscriber Name        TPID    Phone TP
--------------------------------------------------------------
Michael           Ethan                  21456   1122334455
Susan             Johnathan                110   3344556677
Susan             Brad                     110   5566778899

I have tried

SELECT value.value('(QueryXMLData/main/C/@SSN)[1]', 'varchar(50)') AS Customer1,
value.value('(QueryXMLData/main/C/S/@SSN)[1]', 'varchar(50)') AS Subb1
from #tmp

But I would like for it to loop through every value instead of me inserting which line it is supposed to extract from.

Advertisement

Answer

Another way to skin the cat…

SELECT
       n.value('../@Name', 'varchar(50)'),
       n.value('@Name', 'varchar(50)'),
       n.value('@TPID', 'varchar(50)'),
       n.value('(TPIDs/Phone/@TP)[1]', 'varchar(50)')
from #tmp
CROSS APPLY value.nodes('QueryXMLData/main/C/S') n(n)

Demo

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement