Friday, September 24, 2010

SQL Server XML Support

I'm modifying an application that calls stored procedures which return XML. Naturally, more than just the Java has to be modified. I'm finding that I really enjoy working with SQL-Server, especially its more esoteric features. My first attempt FAILED! but, with the help of Microsoft forums, the second attempt WORKED!

I started with this:
SELECT 'Jon Stewart'       as "Employee/name",
       'home'              as "Employee/contact/phone/@type",
       '(555) 555-1212'    as "Employee/contact/phone",
       'cell'              as "Employee/contact/phone/@type",
       '(555) 555-1212'    as "Employee/contact/phone",
       '123 Main Street'   as "Employee/contact/street",
       null                as "Employee/contact/street2",
       'Dallas'            as "Employee/contact/city",
       'TX'                as "Employee/contact/state",
       '75025'             as "Employee/contact/zip"
FOR XML PATH('Employees'), ROOT('doc');
which I thought would give me:
<doc>
  <Employees>
    <Employee>
      <name>Jon Stewart</name>
      <contact>
        <phone type="home">(555) 555-1212</phone>
        <phone type="cell">(555) 555-1212</phone>
        <street>123 Main Street</street>
        <city>Dallas</city>
        <state>TX</state>
        <zip>75025</zip>
      </contact>
    </Employee>
  </Employees>
</doc>
but, the duplication of phone and phone/@type in the above SELECT statement resulted in an error and I had to use the following SELECT statement instead:
SELECT 
  (SELECT 'Jon Stewart' as "name",
    (SELECT 
      (SELECT 
        'home' as "phone/@type",
        '(555) 555-1212' as "phone"
      FOR XML PATH(''),TYPE),
      (SELECT 
        'cell' as "phone/@type",
        '(555) 555-1212' as "phone"
      FOR XML PATH(''),TYPE),
      '123 Main Street' as "street",
      null as "street2",
      'Dallas' as "city",
      'TX' as "state",
      '75025' as "zip"
    FOR XML PATH('contact'), TYPE)
  FOR XML PATH('Employee'),TYPE)
FOR XML PATH ('Employees'),ROOT('doc')