SQL Dynamic CrossTab Stored Procedure (altered version)
create procedure CrossTab2 (@SQL varchar(1000),
@PivotCol varchar(100),
@Summaries varchar(100),
@GroupBy varchar(100),
@OtherFields varchar(100) = Null,
@Debug bit = 0)
AS
set nocount on
set ansi_warnings off
declare @Vals varchar(8000);
declare @Vals2 varchar(8000);
declare @Vals3 varchar(8000);
declare @tmp varchar(1000);
declare @TotalLen int;
set @Vals = '';
set @Vals2 = '';
set @Vals3 = '';
set @TotalLen = len(@SQL) + len(@GroupBy) + Len(ISNULL(@OtherFields,''))
set @OtherFields = isNull(', ' + @OtherFields ,'')
create table #temp (Pivot varchar(100))
insert into #temp
exec ('select distinct convert(varchar(100),' + @PivotCol + ') as Pivot FROM (' + @SQL + ') A')
select @tmp =
replace(replace(@Summaries,'(','(CASE WHEN ' + @PivotCol + '=''' + replace(Pivot,'''','''''') +
''' THEN '),')[', ' END) as [' + Pivot ),
@TotalLen = @TotalLen + Len(@tmp),
@Vals = case when @TotalLen < 7800 then @Vals + ', ' + @tmp else @Vals end,
@Vals2 = case when @TotalLen between 7800 and 15799 then @Vals2 + ', ' + @tmp else @Vals2 end,
@Vals3 = case when @TotalLen between 15800 and 23799 then @Vals3 + ', ' + @tmp else @Vals3 end
from
#Temp
order by
Pivot
drop table #Temp
if (@Debug=0)
exec ( 'select ' + @GroupBy + @OtherFields + @Vals + @Vals2 +
@Vals3 + ' from (' + @SQL + ') A GROUP BY ' + @GroupBy)
else
begin
create table #Temp2 (SQLText Text);
insert into #Temp2 (SQLText)
values ('select ' + @GroupBy + @OtherFields + @Vals + @Vals2 +
@Vals3 + ' from (' + @SQL + ') A GROUP BY ' + @GroupBy);
select * from #Temp2
end
set nocount off
set ansi_warnings on
Legacy Comments
Juver
2005-08-23 |
re: SQL Dynamic CrossTab Stored Procedure (altered version) SQLEXPRESS errors :( Incorrect syntax near the keybord 'Pivot' |
Bob Weston
2006-02-16 |
re: SQL Dynamic CrossTab Stored Procedure (altered version) For your debug mode, I found it more handy to replace the 'false' condition of the 'if' statement to: print ( 'select ' + @GroupBy + @OtherFields + @Vals + @Vals2 + @Vals3 + ' from (' + @SQL + ') A GROUP BY ' + @GroupBy) Rather than inserting to a temp table and selecting the query text out. I'd say that about 2/3 of the query was actually truncated and not returned in the results. Thanks, Bob |
Stephen Turner
2006-05-17 |
re: SQL Dynamic CrossTab Stored Procedure (altered version) this wasn't quite working for me, and not long enough!!! here's an improved version: CREATE procedure CrossTab2 (@SQL varchar(1000), @PivotCol varchar(100), @Summaries varchar(100), @GroupBy varchar(100), @OtherFields varchar(100) = Null, @Debug bit = 0) AS set nocount on SET ANSI_WARNINGS OFF declare @Vals1 varchar(8000) declare @Vals2 varchar(8000) declare @Vals3 varchar(8000) declare @Vals4 varchar(8000) declare @Vals5 varchar(8000) declare @tmp varchar(8000) declare @TotalLen int declare @SafeLen int set @SafeLen = 7800 set @Vals1 = '' set @Vals2 = '' set @Vals3 = '' set @Vals4 = '' set @Vals5 = '' set @TotalLen = len(@SQL) + len(@GroupBy) + Len(ISNULL(@OtherFields,'')) set @OtherFields = isNull(', ' + @OtherFields ,'') create table #temp (Pivot varchar(100)) insert into #temp exec ('select distinct convert(varchar(100),' + @PivotCol + ') as Pivot FROM (' + @SQL + ') A') select @tmp = replace(replace(@Summaries,'(','(CASE WHEN ' + @PivotCol + '=''' + replace(Pivot,'''','''''') + ''' THEN '),')[', ' END) as [' + Pivot ), @TotalLen = @TotalLen + Len(@tmp), @Vals1 = case when @TotalLen between @SafeLen*0 and (@SafeLen*1)-1 then @Vals1 + ', ' + @tmp else @Vals1 end, @Vals2 = case when @TotalLen between @SafeLen*1 and (@SafeLen*2)-1 then @Vals2 + ', ' + @tmp else @Vals2 end, @Vals3 = case when @TotalLen between @SafeLen*2 and (@SafeLen*3)-1 then @Vals3 + ', ' + @tmp else @Vals3 end, @Vals4 = case when @TotalLen between @SafeLen*3 and (@SafeLen*4)-1 then @Vals4 + ', ' + @tmp else @Vals4 end, @Vals5 = case when @TotalLen between @SafeLen*4 and (@SafeLen*5)-1 then @Vals5 + ', ' + @tmp else @Vals5 end from #Temp order by Pivot drop table #Temp if (@Debug=0) begin set nocount off exec ( 'select ' + @GroupBy + @OtherFields + @Vals1 + @Vals2 + @Vals3 + @Vals4 + @Vals5 + ' from (' + @SQL + ') A GROUP BY ' + @GroupBy) set nocount on end ELSE begin Print @totallen Print 'select ' + @GroupBy + @OtherFields Print @Vals1 Print @Vals2 Print @Vals3 Print @Vals4 Print @Vals5 Print ' from (' + @SQL + ') A GROUP BY ' + @GroupBy create table #Temp2 (SQLText Text); insert into #Temp2 (SQLText) values ('select ' + @GroupBy + @OtherFields + @Vals1 + @Vals2 + @Vals3 + @Vals4 + ' from (' + @SQL + ') A GROUP BY ' + @GroupBy); select SQLText, DATALENGTH(SQLText) from #Temp2 end set nocount off |
Steve V
2006-07-27 |
re: SQL Dynamic CrossTab Stored Procedure (altered version) This was just what I was looking for. :) Here is just a little change for SQL Server 2000 or greater, using table variables instead of temp tables. Create procedure CrossTab2 (@SQL varchar(1000), @tpivotCol varchar(100), @Summaries varchar(100), @GroupBy varchar(100), @OtherFields varchar(100) = Null, @Debug bit = 0) AS set nocount on set ansi_warnings off declare @Vals varchar(8000); declare @Vals2 varchar(8000); declare @Vals3 varchar(8000); declare @tmp varchar(1000); declare @TotalLen int; set @Vals = ''; set @Vals2 = ''; set @Vals3 = ''; set @TotalLen = len(@SQL) + len(@GroupBy) + Len(ISNULL(@OtherFields,'')) set @OtherFields = isNull(', ' + @OtherFields ,'') declare @temp table(tpivot varchar(100)) insert into @temp exec ('select distinct convert(varchar(100),' + @tpivotCol + ') as tpivot FROM (' + @SQL + ') A') select @tmp = replace(replace(@Summaries,'(','(CASE WHEN ' + @tpivotCol + '=''' + replace(tpivot,'''','''''') + ''' THEN '),')[', ' END) as [' + tpivot ), @TotalLen = @TotalLen + Len(@tmp), @Vals = case when @TotalLen < 7800 then @Vals + ', ' + @tmp else @Vals end, @Vals2 = case when @TotalLen between 7800 and 15799 then @Vals2 + ', ' + @tmp else @Vals2 end, @Vals3 = case when @TotalLen between 15800 and 23799 then @Vals3 + ', ' + @tmp else @Vals3 end from @Temp order by tpivot if (@Debug=0) exec ( 'select ' + @GroupBy + @OtherFields + @Vals + @Vals2 + @Vals3 + ' from (' + @SQL + ') A GROUP BY ' + @GroupBy) else begin declare @Temp2 table(SQLText Text); insert into @Temp2 (SQLText) values ('select ' + @GroupBy + @OtherFields + @Vals + @Vals2 + @Vals3 + ' from (' + @SQL + ') A GROUP BY ' + @GroupBy); select * from @Temp2 end set nocount off set ansi_warnings on |
Seetha
2006-09-11 |
re: SQL Dynamic CrossTab Stored Procedure (altered version) I have the value for @SQL as this: 'SELECT Practice, CIty, QR_ID, QRQC_Name, Designation, Criticality FROM dbo.SQA_DashBoard_Project_FTE_Details_Refined, vw_SQA_DashBoard_NonQMQC_QRList WHERE QR_ID = QRQC_ID' I get this error - with @SQL truncated after 128 chars Msg 102, Level 15, State 1, Line 2 Incorrect syntax near 'SELECT Practice, CIty, QR_ID, QRQC_Name, Designation, Criticality FROM dbo.SQA_DashBoard_Project_FTE_Details_Refined, vw_SQA_Das'. ANy help? Thanks Seetha |
Sean Dessureault
2008-12-10 |
re: SQL Dynamic CrossTab Stored Procedure (altered version) Keep getting the error "Msg 156, Level 15, State 1, Procedure CrossTab2, Line 32 Incorrect syntax near the keyword 'Pivot'.", on the 5/17/2006 post. |
Dave
2009-02-08 |
re: SQL Dynamic CrossTab Stored Procedure (altered version) I would like to add a WHERE clause to my @SQL to preselect columns using a STRING STARTWITH and ENDWITH range, but the following fails... EXEC CrossTab2 'SELECT InvMonth, SlsRep, Cast(Value AS MONEY) as Value FROM MAXInvoiceDetails WHERE SlsRep >'2'', 'InvMonth', 'Sum(Value ELSE 0)[]', 'SlsRep', '0' What do I need to fix? Thanks |
PaulP
2009-05-08 |
re: SQL Dynamic CrossTab Stored Procedure (altered version) Hi Jeff I'm trying to get this great sp to work but keep getting the error "Incorrect syntax near ','. Incorrect syntax near 'A'". I'm running on SQL 2005 and have replaced Pivot with TPIVOT. I can't figure this out and am running out of time. Can you help. Please. Here is my Select input: SELECT dbo.CalcDate(SalesDate, '2', 'N') AS SalesDate, Category, Isbn, BookTitle, SUM(NetDollars) as SumOfNetDollars, SUM(NetDollars) as SumNetDollars FROM dbo.Sales LEFT JOIN (((Licenses RIGHT JOIN (Categories RIGHT JOIN Books ON Categories.CategoryID = Books.CategoryID) ON Licenses.LicenseID = Books.LicenseID) LEFT JOIN Series ON Books.SeriesID = Series.SeriesID) LEFT JOIN Formats ON Books.FormatID = Formats.FormatID) ON SALES.SalesISBN = Books.BookID LEFT JOIN Customers ON Sales.CustNumber = Customers.CustID LEFT JOIN Channels ON Sales.ChannelID = Channels.ChannelID Where 1 = 1 AND ((Sales.SalesDate >= '6/1/2008' AND Sales.SalesDate <= '8/1/2008')) GROUP BY SalesDate, Category, Isbn, BookTitle Many thanks |
yagava
2009-06-01 |
re: SQL Dynamic CrossTab Stored Procedure (altered version) here with we attacged.pls gothrouh |
Jerry
2009-11-25 |
re: SQL Dynamic CrossTab Stored Procedure (altered version) Jeff I am trying to cnstruct a dynamic crosstab query based on the following: Here is sample data key id comment 112 1 fishing 113 1 reading I want the data to look like this id comment1 comment2 1 fishing reading How should I begin. Is it with a case statement? I do not want to hardcode comment because there are too many scenatios |
Joseph German Ocena
2009-12-11 |
re: SQL Dynamic CrossTab Stored Procedure (altered version) It is not working dude!! My query... Execute Crosstab2 'Select * from view_sched','TechnicalName','max(ClientName)' ,'ClientName' Error: Msg 102, Level 15, State 1, Line 1 Incorrect syntax near ')'. Msg 102, Level 15, State 1, Line 1 Incorrect syntax near 'A'. |
Andy
2010-03-24 |
re: SQL Dynamic CrossTab Stored Procedure (altered version) I know this is quite old now but I had the same problem as Joseph Msg 102, Level 15, State 1, Line 1 Incorrect syntax near ')'. Msg 102, Level 15, State 1, Line 1 Incorrect syntax near 'A'. so I had a play with it and this now works for me. ALTER PROCEDURE CrossTab3 (@SQL VARCHAR(8000), @tpivotCol VARCHAR(100), @Summaries VARCHAR(100), @GroupBy VARCHAR(100), @OrderBy VARCHAR(100) = NULL, @OtherFields VARCHAR(100) = NULL, @Debug bit = 0) AS BEGIN SET NOCOUNT ON; SET ANSI_WARNINGS OFF; DECLARE @Vals VARCHAR(8000); DECLARE @Vals2 VARCHAR(8000); DECLARE @Vals3 VARCHAR(8000); DECLARE @tmp VARCHAR(1000); DECLARE @TotalLen INT; SET @Vals = ''; SET @Vals2 = ''; SET @Vals3 = ''; SET @TotalLen = Len(@SQL) + Len(@GroupBy) + Len(ISNULL(@OtherFields,'')) SET @OtherFields = ISNULL(', ' + @OtherFields ,'') DECLARE @temp table(tpivot VARCHAR(100)); DECLARE @tmpSQL NVARCHAR(4000); SET @tmpSQL='SELECT DISTINCT CONVERT(VARCHAR(100),' + @tpivotCol + ') AS [tpivot] FROM (' + @SQL + ') AS [tmp]'; INSERT @temp EXEC sp_executesql @tmpSQL; SELECT @tmp = REPLACE( REPLACE(@Summaries,'(','(CASE WHEN ' + @tpivotCol + '=''' + REPLACE(tpivot,'''','''''') + ''' THEN ') ,')', ' END) AS [' + REPLACE(tpivot,'''','''''')) + ']', @TotalLen = @TotalLen + Len(@tmp), @Vals = case when @TotalLen < 7800 then @Vals + ', ' + @tmp else @Vals end, @Vals2 = case when @TotalLen between 7800 and 15799 then @Vals2 + ', ' + @tmp else @Vals2 end, @Vals3 = case when @TotalLen between 15800 and 23799 then @Vals3 + ', ' + @tmp else @Vals3 end FROM @Temp WHERE [tpivot] <> '' ORDER BY tpivot SELECT @tmpSql = 'SELECT ' + @GroupBy + @OtherFields + @Vals + @Vals2 + @Vals3 + ' FROM (' + @SQL + ') AS [tmp] GROUP BY ' + @GroupBy + CASE WHEN @OrderBy IS NULL THEN '' ELSE ' ORDER BY ' + @OrderBy END; EXEC (@tmpSQL) ; SET NOCOUNT OFF; SET ANSI_WARNINGS ON; END |