tags:

views:

148

answers:

3

Is it possible to select multiple tables at once? For example, I can do:

SELECT (
  SELECT * FROM Articles
  FOR XML PATH('article'), TYPE
)
FOR XML PATH('articles'), ROOT('data')

and

SELECT (
  SELECT * FROM ArticleTypes
  FOR XML PATH('articleType'), TYPE
)
FOR XML PATH('articleTypes'), ROOT('data')

Can I join both so that I get the following output? I can't use UNION because the table structures don't match.

<data>
  <articles>
    <article>...</article>
    ...
  </articles>
  <articleTypes>
    <articleType>...</articleType>
    ...
  </articleTypes>
</data>
A: 

Each column in a union has only one column name, and that column name is taken from the first query. You can get around that by set columns from the other table to null, instead of omitting them.

select *
from (
    select 
        1 as 'Articles/Id'
    ,   'Name' as 'Articles/Name'
    ,   null as 'ArticleType/Id'
    ,   null as 'ArticleType/Type'
) Articles
union all
select *
from (
    select 
        null as 'Articles/Id'
    ,   null as 'Articles/Name'
    ,   1 as 'ArticleType/Id'
    ,   'Type' as 'ArticleType/Type'
) ArticleType
FOR XML PATH(''), ROOT('data')

This results in:

<data>
    <Articles>
        <Id>1</Id>
        <Name>Name</Name>
    </Articles>
    <ArticleType>
        <Id>1</Id>
        <Type>Type</Type>
    </ArticleType>
</data>
Andomar
Your result doesn't match my output example (but I could probably modify to do so). Also, I would like to avoid specifying all the columns because there are lots of them. This is basically a dump of several tables. I could merge it on the application side if I really have to, but I'm hoping SQL can do it.
Nelson
@Nelson: You can wrap the articles again, like `Article/Articles/Id`. Like the answer says, a union requires all columns in all parts of the union. I don't know of a way around that
Andomar
@Andomar: Last thing I'd like to clear up. I understand how a union works and that it requires all columns. Is it possible to do what I want *without* a union?
Nelson
@Nelson: Let me put it this way: if you find a way to do this without repeating columns, I'd be interested in learning it :)
Andomar
@Andomar: Alright, I'll work with what I have. If you're using a stored procedure, you could in theory save each query to a variable and simply concatenate the strings. The indentation would be a little off and I'm not sure how performant it would be. I'm not going to use that, but it may be an option...
Nelson
Just for kicks I tried out the concatenation and it works quite well. Indentation is not a problem since I'm using RAW and there is no whitespace.
Nelson
@Nelson: Concatenation with variables might be limited to 8k data, but you could always concatenate to a `varchar(max)` column in a temporary table
Andomar
A: 

Depending on the version of SQL Server you are using. How about something like this stack overflow post?

Garett
A: 

It is possible to NOT list out all the columns in the tables, NOT have to use a UNION and not have to have repeating columns using the following method:

  1. Grab the data you need into temp tables (in my case it was from a different server using openquery so it was simpler but can be skipped if the rows are local)
  2. Cursor through your main control table and for each Primary Key row:
    • generate your multi-level XML Path Output and place it into an xml variable
    • insert your xml variable into an output tempXMLOutput table with a column of type xml
  3. Once you fetched all data in the cursor output your tempXMLOutput table

This will display all the data without the funky repeating columns and it does not take long to code for.

ZVV