10

Gday All,

I've written some code to dynamically Pivot a table like SQL Server : Transpose rows to columns

The code looks like this

DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX)

SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(FieldName)
            FROM CORE_Items_Extra
            WHERE Not(FieldName = '')
            ORDER BY 1
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'),1,1,'')

SET @sql = 'SELECT ItemID, ' + @cols + '
              FROM
            (
              SELECT ItemID,  FieldValue, FieldName
                FROM CORE_Items_Extra
            )  AS SourceTable
            PIVOT
            (
              MAX(FieldValue) FOR FieldName IN (' + @cols + ')
            ) AS PivotTable;'

EXECUTE(@sql)

Which works perfectly BUT I want to use it within a View, I've tried copying the code to a view and it works but wont save as it doesn't like the Declare statements in the view, I've got it working in a Stored Procedure but cant use Stored Procedures in a View, I think I need to have it as a Table-Valued Function but cant use the Execute statement within a TBF. I need to combine this data with another table in a view, and would like to keep it dynamic, so any ideas would be greatly appreciated :) We are using SQL 2008 R2

2 Answers 2

9

I suggest you to create some view (myView in sample below) and then write stored procedure that will alter your view like:

CREATE VIEW myView
AS
SELECT 1
GO

CREATE PROCEDURE myStoredProc
AS
BEGIN
    DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX)

    SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(FieldName)
                FROM CORE_Items_Extra
                WHERE Not(FieldName = '')
                ORDER BY 1
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)'),1,1,'')

    SET @sql = 'ALTER VIEW myView
                AS
                SELECT ItemID, ' + @cols + '
                  FROM
                (
                  SELECT ItemID,  FieldValue, FieldName
                    FROM CORE_Items_Extra
                )  AS SourceTable
                PIVOT
                (
                  MAX(FieldValue) FOR FieldName IN (' + @cols + ')
                ) AS PivotTable;'

    EXECUTE(@sql)
END
GO

Run this SP within job once or more in a day.

Sign up to request clarification or add additional context in comments.

Comments

1

Given what your trying to do I believe the only option is to use a stored procedure for this. Views are limited to SELECT statements with CTE's and functions. More complex executions won't work.

A couple of other ideas:

1) If you want to hide the workings you could insert the result set into a table and maybe schedule your procedure with the dynamic code to run daily in an agent job or something to refresh the table.

2) Have a look at database triggers and refresh the table with new data at the point a user runs a SELECT against it. This isn't ideal and would course performance issues if you have lots of users requiring the same dataset so very much a dirty workaround. In fact why am I even suggesting this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.