You are on page 1of 2

XML

One aspect of foreign keys and indexes that we need to contend with are column lists. Indexes
can contain any number of key columns and (optionally) include columns. A foreign key typically
consists of a one-column-to-one-column relationship, but could be comprised of two, three, or
more columns. We’d like to quickly generate a column list, and do so without the need for loops
or multiple additional queries.

A list can be generated using string manipulation, and can be done so very efficiently. The
following example creates a comma separated list using table names from sys.tables:

2 DECLARE @string NVARCHAR(MAX) = '';

3 SELECT @string = @string + name + ','

4 FROM sys.tables

5 WHERE tables.is_ms_shipped = 0

6 ORDER BY tables.name;

7 SELECT @string = LEFT(@string, LEN(@string) - 1);

8 SELECT @string;

This syntax, in which we SELECT a string equal to itself plus additional table data allows that data
to be compressed into the @string itself. While this syntax is extremely efficient, it cannot be
combined easily with the SELECT of other columns. In order to get the best of both worlds and
create a comma separated list while also gathering additional metadata, we’ll use XML instead.

With XML, we can cram the same data as above into an XML object, and then use STUFF to put it
into a string, delimited by commas, just as above. The syntax will look like this:

1  

2 DECLARE @string NVARCHAR(MAX) = '';

3 SELECT @string =

4 STUFF(( SELECT ', ' + tables.name

5 FROM sys.tables
6 WHERE tables.is_ms_shipped = 0

7 ORDER BY tables.name

8 FOR XML PATH('')), 1, 2, '')

9 SELECT @string;

10  

In both of the scenarios above, the output will be the expected CSV, which looks like this:

This strategy will allow us to collect index metadata, for example, while also compiling index
column lists form within the same statement. While the TSQL isn’t as simple as if we collected
each data element separately, it is more efficient and requires significantly less work to gather
what we are looking for.

You might also like