I've been working on alot of SQL Server lately due to the current project i'm assigned to and I found myself this morning needing a query that would truncate all the tables in one of my staging database. My initial thought is that I can do this using a cursor that would hold all truncate statements and execute each one of them one at a time so within 5 minutes i was able to build a query that looks like this:
--declare a variable that would hold the query to be executedDECLARE @TruncateQuery varchar(4000)-- create a cursor that would hold our truncate statementsDECLARE TruncateQuerries CURSOR LOCAL FAST_FORWARDFOR SELECT N'TRUNCATE TABLE ' + QUOTENAME(TABLE_SCHEMA) + N'.' + QUOTENAME(TABLE_NAME)FROM INFORMATION_SCHEMA.TABLESWHERE TABLE_TYPE = 'BASE TABLE' AND OBJECTPROPERTY ( OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + N'.' + QUOTENAME(TABLE_NAME) ), 'IsMSShipped') = 0-- read our truncate statementsOPEN TruncateQuerries-- loop thru each statement in our truncate statement cursorFETCH NEXT FROM TruncateQuerries INTO @TruncateQuery WHILE @@FETCH_STATUS = 0BEGIN --execute the statement EXEC(@TruncateQuery) --assign the current truncate statement to our @TruncateStatement variable FETCH NEXT FROM TruncateQuerries INTO @TruncateQuery
END-- close our cursorCLOSE TruncateQuerries-- and free up the resourcesDEALLOCATE TruncateQuerries
Looks great right? Then I realized what my good friend Jon Galloway told me once that there are hidden stored procedures in SQL Server and 1 of those stored proc is sp_MSforeachtable. It's an undocumented sp so you won't find anything about it in the SQL Books Online. What this stored procedure basically does is that it lets you execute a command or a set of commands against all tables inside a database. Before we go into further detail lets look at the parameters that sp_MSforeachtable expects.
exec @RETURN_VALUE=sp_MSforeachtable @command1, @replacechar, @command2, @command3, @whereand, @precommand, @postcommand
Where:(description taken from [LINK])
All other parameters are optional except for @command1 which is first statement that would be executed.
Now, lets rewrite our truncate table query from above to use the sp_MSForeachtable procedure:
EXEC [sp_MSforeachtable] @command1="TRUNCATE TABLE ?"
What??? Tha't it? 1 line? Crazy huh? I didn't realized that it was that easy until i tried it. Man, If i knew this when I started writing my query above I could have not wasted 5 minutes of my life in something that can be done in 10 seconds. Thanks for hiding feature this Micrsoft!
But wait! There's more, now i've truncated my tables i need a way to reseed all the identity columns on my database:
EXEC [sp_MSforeachtable] @command1="DBCC CHECKIDENT (?, RESEED, 100)"
What??? Another 1 liner? Whats even better is that I could also REINDEX all the tables in my DB with one line of beautiful SQL code:
EXEC [sp_MSforeachtable] @command1="DBCC DBREINDEX('?')"
Wanna show progress message on each execution? Try this version:
EXEC [sp_MSforeachtable] @command1="RAISERROR('DBCC DBREINDEX(''?'') ...',10,1) WITH NOWAIT DBCC DBREINDEX('?')"
Oh, Ma! I can't believe being a programmer could be this easy. ;) I hope i could save someone's precious time by proving this example because i know it would save mine in the future.
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.