Tally Function with Error Checking by Jeff Moden Greased Lightning Tally Function with Error Checking by Jeff Moden SPID Lightning Rounds, Detroit, Mi 12 September 2013
Your Speaker - Jeff Moden 17 years experience working with SQL Server Mostly Self Taught One of Leading Posters on SQLServerCentral.com More than 33,000 posts (heh… some are even useful) 30+ articles on the “Black Arts” of T-SQL http://www.sqlservercentral.com/Authors/Articles/Jeff_Moden/80567/ Member since 2003 SQL Server MVP 2008 thru 2013 Winner of the “Exceptional DBA” award for 2011 Lead Application DBA, Data Architect, and SQL Mentor for Proctor Financial, Inc. SQL Server is both my profession and my hobby (Yeah, I know… I need to get a life ;-) Tally Function with Error Checking 12 September 2013 © Copyright by Jeff Moden - All Rights Reserved
Agenda The Tally Function Error Checking in a Function A high performance “readless” replacement for the Tally Table Error Checking in a Function How to check for and display meaningful errors from a function Quick Demo of Performance and Error Messages Tally Function with Error Checking 12 September 2013 © Copyright by Jeff Moden - All Rights Reserved
The Tally Function
Reference Material Learn What a Tally Table/Function is and How It Replaces Certain Types of Loops: http://www.sqlservercentral.com/articles/T-SQL/62867/ How to Split Strings: http://www.sqlservercentral.com/articles/Tally+Table/72993/
The Tally Function Tally Function with Error Checking CREATE FUNCTION dbo.fnTally --===== Define the I/O for this function (@BaseValue INT, @MaxValue INT) RETURNS TABLE WITH SCHEMABINDING AS RETURN WITH --===== Generate up to 1 Million rows ("En" indicates the power of 10 produced) --E1(N) AS (SELECT 1 FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))n(N)), E1(N) AS (SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1), E3(N) AS (SELECT 1 FROM E1 a,E1 b,E1 c), E6(N) AS (SELECT 1 FROM E3 a,E3 b) --===== Conditionally start the sequence at 0 SELECT N = 0 WHERE @BaseValue = 0 UNION ALL --===== Enumerate the rows generated by the cascading CTEs (cCTE) SELECT TOP (@MaxValue) N = CAST(ROW_NUMBER()OVER(ORDER BY (SELECT N)) AS INT) FROM E6 ; Explain why this is an “Inline” function and why that’s important for performance. Explain how the “cascading CTE’s” work as a “row source”/”pseudo-cursor”. Explain the difference between the commented out VALUES statement and E1. Explain how the combination of ROW_NUMBER() and TOP produce values from 1 to @MaxValue. Explain how the SELECT N=0 WHERE @BaseValue=0 works to start a sequence at 0 or 1. Tally Function with Error Checking 12 September 2013 © Copyright by Jeff Moden - All Rights Reserved
Error Checking in a Function
Error Checking in a Function CREATE FUNCTION dbo.fnTally --===== Define the I/O for this function (@BaseValue INT, @MaxValue INT) RETURNS TABLE WITH SCHEMABINDING AS RETURN WITH --===== Generate up to 1 Million rows ("En" indicates the power of 10 produced) --E1(N) AS (SELECT 1 FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))n(N)), E1(N) AS (SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1), E3(N) AS (SELECT 1 FROM E1 a,E1 b,E1 c), E6(N) AS (SELECT 1 FROM E3 a,E3 b) --===== Create understandable error messages if the parameters are incorrect. SELECT N = CAST('Util.dbo.fnTally: @BaseValue must be 0 or 1' AS INT) WHERE ISNULL(@BaseValue,-1) NOT BETWEEN 0 AND 1 UNION ALL SELECT N = CAST('Util.dbo.fnTally: @MaxValue must be between 0 and 1 Million' AS INT) WHERE @MaxValue > 1000000 --Negative values taken care of by TOP error --===== Conditionally start the sequence at 0 SELECT N = 0 WHERE @BaseValue = 0 --===== Enumerate the rows generated by the cascading CTEs (cCTE) SELECT TOP (@MaxValue) N = CAST(ROW_NUMBER()OVER(ORDER BY (SELECT N)) AS INT) FROM E6 ; Explain that this is identical to the previous code (the function) with some added room. Explain that RAISERROR and tradition error checking methods cannot be used. When the error checking code comes on screen, explain the error checking message and conditions for each error check. Tally Function with Error Checking 12 September 2013 © Copyright by Jeff Moden - All Rights Reserved
(See 01 fnTally with Error Checking.sql) Quick Demo (See 01 fnTally with Error Checking.sql)
Quick Review The Tally Function Error Checking in a Function A high performance “readless” replacement for the Tally Table Error Checking in a Function How to check for and display meaningful errors from a function Quick Demo of Performance and Error Messages It’s real fast and the error messages help, but a real Tally Table is still faster. Tally Function with Error Checking 12 September 2013 © Copyright by Jeff Moden - All Rights Reserved
See me at the end of tonight’s presentations. Q’n’A See me at the end of tonight’s presentations. Tally Function with Error Checking 12 September 2013 © Copyright by Jeff Moden - All Rights Reserved
Tally Function with Error Checking by Jeff Moden Greased Lightning Tally Function with Error Checking by Jeff Moden Thanks for Listening SPID Lightning Rounds, Detroit, Mi 12 September 2013