A few SQL Tricks and Tips
Posted by Chris Alcock on Wednesday 11th July 2007 at 07:07 pm | Tagged as: Database, Development, SQL
Undocumented Stored Procedure 1 – sp_MSForEachDB
There are a number of reasons that you might need to run the same (or similar) bits of SQL against a number of similar databases. I find myself doing this when I update some part of an application that runs against a number of individual client databases on the same server. In my case, the databases are consistently named in the format ‘client’ + ‘ApplicationName – i.e. ReflectivePerspectiveBLOG
sp_MSForEachDB is a built in SQL Server stored procedure which is undocumented in Books Online, but helps us out in this situation, allowing us to run a command on each database on the server
EXEC sp_MSForEachDB @command1 = '
use [?]
if (db_name() like '%BLOG')
BEGIN
--Perform our operation
update foo set bar = 1 where wibble=2
END
'
Undocumented Stored Procedure 2 – sp_MSForEachTable
Another related stored proceedure is sp_MSForEachTable – this one allows you to do things to each table in the database:
EXEC sp_MSForEachTable @command1 = '
select top 10 * from ?
'
SET vs SELECT to initialize variables
There are two ways of allocating values to variables in TSQL – SET and SELECT. Many people get into the habit of using SET to initialize their variables, like so
SET @foo = 1
SET @bar = 2
SET @wibble = 3
For performance purposes this is quite in-efficient as each use of SET is the equivaent of a SELECT statement.
SELECT, on the other hand has the advantage that it is able to set multiple variables at once:
SELECT @foo = 1, @bar = 2, @wibble=3
This single select statement is the equivalent of one of the SET statements above. The performance advantages of this increase when allocating values to variables from database tables:
SET @foo = (select foo from table where 1=1)
SET @bar = (select bar from table where 1=1)
does the same as the following statement, but only executes the query against the database once.
SELECT @foo = foo, @bar = bar from table where 1=1
Table Variables
Table variables are very useful and often forgotten about feature of SQL Server. You can use them much as you might a temporary table, however they have the added benefit that they will clean up after them selves, so you don’t have to remember to do the drop table #foo.
You can create Table Variables like so:
declare @tableVar table (col1 int, col2 int)
and from then on you can use them much as you would any other table
insert into @tableVar (col1, col2) values(1,2)
select * from @tableVar
Hi Chris,
I like those foreach stored procedures – good find!
I wrote a post with some performance tips a while ago: http://harriyott.com/2006/01/sql-server-performance-tips.aspx
Very handy for running updates across multiple databases from SQL Server Managament Studio, but it’s worth mentioning that since they’re undocumented they could disappear with any further release/service pack – so be careful before considering using them in your application!
That is a very good point Danny – the fact that they are undocumented (and probably unsupported too) does mean that relying on them may be dangerous in the long term. Even if they do remove them from later versions of the database engine they would be easy enough to re-introduce as the source for the stored procedures is available via sp_helptext, and at a quick glance they seem to use pretty standard TSQL under the hood.
Awesome, good find! I agree, you don’t want to “rely” on these, but it’s definitely nice when you’re doing analysis. I have a few scripts that help me find tables with certain values in the table or column names, it’ll be nice to be able to use it now across all databases too.