One way to do this: use sp_msForEachDb.
-- Round 1 -------
Call this system procedure with a varchar parameter. (It's actually a LOT messier than this, check the code in the master database if you want to know what it's really doing.)
The parameter must be a chunk of dynamic code -- for example,
DECLARE @DemoParameter varchar(1000)
SET @DemoParameter = 'SELECT MyCol from MyTable where CreatedOn between ''Jan 1, 1980'' and ''Dec 21, 2012'''
EXECUTE sp_msForEachDb @DemoParameter
This would run the query against every database on the SQL instance, returning one set per database -- except for those databases that didn't have the necessary table(s), which would throw an error (particularly the system databases). This leads us to...
-- Round 2 ---------
Within the dynamic code, as databases are iterated over all instances of the question mark ? will be replaced with the name of the currently being processed database. You can use this to filter which databases are to be processed, and which aren't. Note also that the "current" database will not be changed by the routine, you have to do that yourself. This gives us code like:
SET @DemoParameter = '
IF ''?'' like ''%Foo%''
BEGIN
USE ?
SELECT MyCol from MyTable where CreatedOn between ''Jan 1, 1980'' and ''Dec 21, 2012''
'
This would run the query only against those databases whose names contain the characters "foo". Possibly you could check for the presence of the table within each database; other methods suggest themselves.
This will shotgun back one dataset for each database, which doesn't help too much if you need them all in one neat and orderly data set, and that gets us to...
-- Round 3 ------------
Briefly: create a temp table, and populate it from within the dynamic query. As I show below, you can include the name of the database, and ever the server name -- very useful when your questing for lost data across dozens of databases spread across a handful of servers.
Create (or clear) the temp table:
IF object_id('tempdb.dbo.##Foo') is null
CREATE TABLE ##Foo
(
ServerName varchar(100) not null
,DBName varchar(100) not null
-- Add your own columns here
,MyCol int not null
)
ELSE
--Option: Delete this line to not clear on each run
TRUNCATE TABLE ##Foo
Run the code (this is my main template, you can easily work @DemoParameter back in there):
EXECUTE sp_msForEachDB '
IF ''?'' like ''%Foo%''
BEGIN
USE ?
INSERT ##Foo
select @@servername, db_name()
,MyCol
from MyTable
END
'
...and that should produce a single temp table with your data. Test this out, I wrote this without actually testing the code, and typso will
silp in. (#temp tables should work as well as ##temp, I generally do this with ad-hoc system support issues)