• subscribe
December 18, 2006 12:00 AM

PIVOT on Steroids

Encapsulate PIVOT workarounds into a dynamic, flexible procedure
SQL Server Pro
InstantDoc ID #94268
Downloads
94268.zip

SQL Server 2005’s new PIVOT operator simplifies the process of rotating data from rows to columns for flexible analysis. However, as I described last month, PIVOT has some limitations (see “Enhancing PIVOT for Crosstab Queries,” InstantDoc ID 93907). Not only are the grouping columns implicit, increasing the potential for writing code that produces undesired results, but the PIVOT IN list (which contains rotation elements) isn’t dynamic. In addition, grouping, rotation, and aggregation columns must be base columns in the table you provide as input, and you can’t rotate more than one column or specify more than one aggregation.

Last month, I showed you how to circumvent most of these limitations by providing a table expression (a derived table or common table expression—CTE) to the PIVOT operator as input and “preparing” columns that result from expressions. I also explained how to use dynamic SQL to make the PIVOT column dynamic.

This month, I show you how to encapsulate all this workaround logic into a stored procedure to provide a flexible and more complete solution for dynamic pivoting needs. Because this solution uses dynamic SQL, which can expose your system to security risks, I also share tips for helping you safely use the procedure. The sp_pivot and usp_pivot stored procedures that I describe are from Inside Microsoft SQL Server 2005: T-SQL Programming (Microsoft Press, 2006), which I wrote with Dejan Sarka and Roger Wolter.

Powerful Pivoting Logic
The sp_pivot stored procedure delivers powerful, dynamic pivoting logic. Run the code in Listing 1, to create sp_pivot in the master database. As I noted, the stored procedure uses dynamic SQL, which opens the door to serious SQL injection risks. (If you aren’t familiar with SQL injection, I urge you to read the “SQL Injection” section in SQL Server 2005 Books OnlineBOL.) After I explain sp_pivot’s pivoting logic, I’ll cover measures you can take to mitigate these security risks.

Before I dig into sp_pivot’s interface and implementation, I want to discuss the stored procedure’s name and the fact that I created the stored procedure in the master database. A stored procedure whose name you prefix with the characters sp_ and that you create in the master database has special behavior. You can invoke the procedure while connected to any database without having to database-qualify the procedure name:

USE Northwind;
EXEC dbo.sp_pivot <arguments>;

Thus, the execution context of dynamic SQL isn’t that of the master database but rather the context of your connection (Northwind, in this case). Furthermore, you can be connected to any database and force the context of the procedure’s execution (in terms of dynamic SQL) to be whatever database you qualify the procedure name with. For example, the following statement forces the execution context of dynamic SQL to that of the Northwind database, regardless of which database you’re connected to:

EXEC Northwind.dbo.sp_pivot
 <arguments>;

Note that Microsoft doesn’t recommend creating stored procedures in the master database using the sp_ prefix and doesn’t guarantee any support if you decide to do so. To adhere to Microsoft’s recommendations, you might prefer to create the stored procedure in all user databases in which you might need it and use a different prefix in its name. This approach, of course, would require you to maintain multiple copies of the stored procedure. Now, let’s see how I implemented sp_pivot.

5 Parameters
The sp_pivot stored procedure accepts five input parameters: @query, @on_rows, @on_cols, @agg_func, and @agg_col. The @query parameter represents the input table to the PIVOT operator. The parameter can be a table or view name or even a query that produces a table result. The stored procedure’s code determines whether @query contains a valid table or view name and, if so, constructs a SELECT query against the object:

SET @query = N’SELECT * FROM ‘
+ @query;

If @query doesn’t contain a valid table or view name, the stored procedure assumes it contains a query to begin with.

The @on_rows parameter represents the grouping columns. The stored procedure requires you to specify the grouping columns explicitly, unlike the PIVOT operator. You can specify one or more columns separated by commas, or you can specify expressions such as

@on_rows = N’EmployeeID,  
  MONTH(OrderDate)
  AS OrderMonth’

The @on_cols parameter represents the rotation column. Here, you can specify a column name or expression; you don’t specify the actual rotation elements. The stored procedure uses dynamic SQL to determine the rotation elements. If you want to rotate order years, for example, you can specify the expression

@on_cols = N’YEAR(OrderDate)’

If you want to rotate multiple columns, you can provide an expression that concatenates elements. So, if you want to rotate shippers and order years, you can specify the expression

@on_cols = N’CAST(ShipVia
  AS VARCHAR(10)) + ‘’_’’ +
  CAST(YEAR(OrderDate)
  AS VARCHAR(10))’

The @agg_func parameter represents the aggregate function you want to use (e.g., SUM, MIN, MAX, COUNT):

@agg_func = N’SUM’


ARTICLE TOOLS

Comments
  • meganbearly
    4 years ago
    Oct 13, 2008

    Hi dianagele!

    Thanks so much for your feedback. I passed your question on to Itzik Ben-Gan, whose response is below.

    “Yes it is. It would be unreasonable for Microsoft to add a feature if they’re not planning to support it in future versions. And before dropping support for a feature, they announce deprecation way ahead in the list of deprecated features in Books Online.”

    Please let me know if you have any more questions.

    Thanks!

    Megan Keller

    Associate Editor, SQL Server Magazine

    mkeller@sqlmag.com

  • Claudia
    4 years ago
    Oct 10, 2008

    Extremely helpful.
    Question: is the PIVOT function to be supported beyond 2005? Future visions to keep it?
    When introduced there was no information if they were going to keep this.

  • Anne
    5 years ago
    Jul 03, 2007

    AnilDesai, thanks for writing! Glad you found Itzik's article helpful.
    --Anne Grubb, Web Lead Editor, SQL Server Magazine and Windows IT Pro

  • Anil
    5 years ago
    Jul 02, 2007

    The sample code and analysis are extremely helpful. This will save me hours of hard work!

You must log on before posting a comment.

Are you a new visitor? Register Here