enter image description hereWe have DWH server working on SQL Server 2016 which we planning to move another server.
But we have some databases which is about 2T but this databases in real size about 400G i mean if i will shrink these database they will be about 400G.
As you know DWH servers always has a drop and create objects.
I am searching about shrink when backup and restore to new server but i don't see for Ms SQL SERVER. Is there any way to migrate to new server with real size databases ?
You Can Shrink The Database Before Taking Backup.
DECLARE #string NVARCHAR(4000),
#Strt INT ,
#END INT ,
#DBName NVARCHAR(255),
#Log_Size DECIMAL(18,5),
#Log_Name NVARCHAR(25),
#String_sql NVARCHAR(MAX)
CREATE TABLE #t (srno INT IDENTITY(1,1),filename NVARCHAR(255),DBNAME NVARCHAR(50))
CREATE TABLE #Tmp_logfile (fileName NVARCHAR(25),file_size DECIMAL(12,5),log_Name NVARCHAR(25))
-- file_id =2 Log File & file_id =1 MDf File NAme
INSERT INTO #Tmp_logfile (fileName,file_size,log_Name)
SELECT a.NAME , CONVERT(DECIMAL(12,5),ROUND(b.size/128.000,5)),b.name
FROM SYS.DATABASES a
INNER JOIN SYS.MASTER_FILES b ON a.database_id=b.database_id
WHERE a.database_id > 4 AND b.file_id =2
INSERT INTO #t
SELECT
'USE [' + d.name + N']' + CHAR(13) + CHAR(10)
+ 'DBCC SHRINKFILE (N''' + mf.name + N''' , 20)'
+ CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) as fileName,d.name
FROM
sys.master_files mf
JOIN sys.databases d
ON mf.database_id = d.database_id
WHERE d.database_id > 4 AND mf.file_id=2;
SET #Strt=1
SELECT #END= Max(Srno)FROM #t
EXEC sp_msforeachdb '
IF ''?'' not in (''master'',''model'',''msdb'',''tempdb'')
begin
exec (''ALTER DATABASE [?] SET RECOVERY SIMPLE;'')
print ''?''
end'
While #Strt<=#END
BEGIN
SELECT #string= FileName,#DBName= DBNAME FROM #t WHERE srno= #Strt
SELECT #Log_Size= file_size FROM #Tmp_logfile WHERE fileName= #DBName
IF #Log_Size > 5000 BEGIN -- Limit The Log Size After which Log file to be Shrink for EG I Had Select 5 GB
PRINT (#string)
EXECUTE (#string)
END
SET #Strt=#Strt+1
END ---- SHRINKING Log File END Here
EXEC sp_msforeachdb '
IF ''?'' not in (''master'',''model'',''msdb'',''tempdb'')
begin
exec (''ALTER DATABASE [?] SET RECOVERY FULL;'')
print ''?''
end'
DROP TABLE #t
DROP TABLE #Tmp_logfile
Related
I have a few SQL databases, that I inherited.
I have a fresh install of SQL 2012
I have attached the databases to the server without an issue.
Yet, where I run Select * From sys.database_files; they are not in there, but when I run Select * From sys.master_files; they are.
This is messing up some code I am attempting to write by throwing the following errors:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near 'I:'.
Msg 8985, Level 16, State 1, Line 1
Could not locate file 'I:\SQL Databases\Cloud.CMS_log.ldf' for database 'master' in sys.database_files. The file either does not exist, or was dropped.
How can I fix it so they are there in sys.database_files so my code runs?
Declare #TempDBList Table
(
Id int,
DBName VarChar(250),
FileType int,
DBFile VarChar(1000)
);
Declare #BackupLocation VarChar(Max) = 'I:\SQL Databases\Backup';
Declare #FileLocation VarChar(Max);
Declare #DBName VarChar(250);
Declare #FileType Int;
Declare #DBBackup VarChar(Max);
Declare #LogBackup VarChar(Max);
Declare #Sql VarChar(Max);
Insert Into #TempDBList
(id, DBName, FileType, DBFile)
Select a.database_id DBid, a.Name , b.type FileType, b.physical_name As FileLocation
From sys.databases a
Inner Join sys.master_files b On b.database_id = a.database_id
Where b.state = 0 AND a.database_id > 4;
Select #DBName = DBName, #FileType = FileType, #FileLocation = DBFile From #TempDBList Order By DBName;
While ##ROWCOUNT <> 0
Begin
--- Set all databases to Simple Recovery
Set #Sql = 'Alter DATABASE ' + QUOTENAME(#DBName) + ' Set RECOVERY SIMPLE';
Exec(#Sql);
Set #DBBackup = #BackupLocation + #DBName + '\' + #DBName + '_' + Convert(Varchar(500), GetDate(), 112)+ '.bak';
Set #LogBackup = #BackupLocation + #DBName + '\' + #DBName + '_' + Convert(Varchar(500), GetDate(), 112)+ '.log.bak';
If #FileType = 1
Begin
Set #Sql = 'Backup Database ' + QUOTENAME(#DBName) + ' To Disk = ' + #DBBackup;
Exec(#Sql);
Exec('DBCC SHRINKFILE(''' + #FileLocation + ''', TruncateOnly)');
End
Else If #FileType = 0
Begin
Set #Sql = 'Backup Log ' + QUOTENAME(#DBName) + ' To Disk = ' + #LogBackup;
Exec(#Sql);
Exec('DBCC SHRINKFILE(''' + #FileLocation + ''', TruncateOnly)');
End
End
Screenshot for both sys.database_files & sys.master_files
http://prntscr.com/57p49b
sys.master_files is a system wide view and will show you all the files on the instance you are connected to (where you have sufficient permission), sys.database_files is a per database view, and will only show files in the specified database. You either need to connect to the correct database to see the files, e.g:
USE Master;
SELECT *
FROM sys.database_files;
Or use the 3 part object name:
SELECT *
FROM master.sys.database_files;
EDIT
I can only apologise for not explaining myself very well, but the above does point out why you cannot see files in sys.database_files that you can see in sys.master_files.
Look at the following screenshot:
You can see that after connecting to a different database (USE TestDB) different files are showing in sys.database_files, but the record count (and the actual records) in sys.master_files is the same regardless of database.
Now, looking at your actual error:
Could not locate file 'I:\SQL Databases\Cloud.CMS_log.ldf' for database 'master' in sys.database_files.
This explains the problem, you are connected to the database master, so sys.database_files would only show the files in the master database (master, and masterlog). You are looking for CMS_log which is presumably located in the database CMS, so to view this file in sys.database_files you would need to run:
USE CMS;
SELECT * FROM sys.database_files;
Or
SELECT * FROM CMS.sys.database_files;
Your actual error comes because you are trying to shrink the file CMS_Log while connected to the master database, which you cannot do, you would need to run:
USE CMS;
DBCC SHRINKFILE('CMS_Log', TRUNCATEONLY);
Hopefully this explains why you are getting the error.
FULL SCRIPT
DECLARE #BackupLocation VARCHAR(MAX) = '',
#DBName SYSNAME,
#DataFile SYSNAME,
#LogFile SYSNAME,
#SQL NVARCHAR(MAX);
DECLARE FileCursor CURSOR STATIC FORWARD_ONLY READ_ONLY
FOR
SELECT DBName = d.Name,
DataFile = MAX(CASE WHEN f.Type = 0 THEN f.Name END),
LogFile = MAX(CASE WHEN f.Type = 1 THEN f.Name END)
FROM sys.databases d
INNER JOIN sys.master_files f
ON d.database_id = f.database_id
WHERE d.Name NOT IN ('master', 'tempdb', 'model', 'msdb')
AND d.Name NOT LIKE 'ReportServer$%'
GROUP BY d.Name;
OPEN FileCursor;
FETCH NEXT FROM FileCursor INTO #DBName, #DataFile, #LogFile;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = '
USE ' + QUOTENAME(#DBName) + ';
ALTER DATABASE ' + QUOTENAME(#DBName) + ' SET RECOVERY SIMPLE;
BACKUP DATABASE ' + QUOTENAME(#DBName) + ' TO DISK = ''' + #BackupLocation +
+ #DBName + '_' + CONVERT(VARCHAR(8), GETDATE(), 112) + '.bak'';
ALTER DATABASE ' + QUOTENAME(#DBName) + ' SET RECOVERY FULL;
BACKUP LOG ' + QUOTENAME(#DBName) + ' TO DISK = ''' + #BackupLocation +
+ #DBName + '_' + CONVERT(VARCHAR(8), GETDATE(), 112) + '.log.bak'';
DBCC SHRINKFILE(' + #DataFile + ', TRUNCATEONLY);
DBCC SHRINKFILE(' + #LogFile + ', TRUNCATEONLY);';
EXECUTE sp_executesql #SQL;
FETCH NEXT FROM FileCursor INTO #DBName, #DataFile, #LogFile;
END
CLOSE FileCursor;
DEALLOCATE FileCursor;
This generates and executes a command like the following for each database:
USE [TestDB];
ALTER DATABASE [TestDB] SET RECOVERY SIMPLE;
BACKUP DATABASE [TestDB] TO DISK = 'I:\SQL Databases\Backup\TestDB_20141119.bak';
ALTER DATABASE [TestDB] SET RECOVERY FULL;
BACKUP LOG [TestDB] TO DISK = 'I:\SQL Databases\Backup\TestDB_20141119.log.bak';
DBCC SHRINKFILE(TestDB, TRUNCATEONLY);
DBCC SHRINKFILE(TestDB_log, TRUNCATEONLY);
I have (for testing purposes) many dbs with the same schema (=same tables and columns basically) on a sql server 2008 r2 instance.
i would like a query like
SELECT COUNT(*) FROM CUSTOMERS
on all DBs on the instance. I would like to have as result 2 columns:
1 - the DB Name
2 - the value of COUNT(*)
Example:
DBName // COUNT (*)
TestDB1 // 4
MyDB // 5
etc...
Note: i assume that CUSTOMERS table exists in all dbs (except master).
Try this one -
SET NOCOUNT ON;
IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #temp
(
[COUNT] INT
, DB VARCHAR(50)
)
DECLARE #TableName NVARCHAR(50)
SELECT #TableName = '[dbo].[CUSTOMERS]'
DECLARE #SQL NVARCHAR(MAX)
SELECT #SQL = STUFF((
SELECT CHAR(13) + 'SELECT ' + QUOTENAME(name, '''') + ', COUNT(1) FROM ' + QUOTENAME(name) + '.' + QUOTENAME(#TableName)
FROM sys.databases
WHERE OBJECT_ID(QUOTENAME(name) + '.' + QUOTENAME(#TableName)) IS NOT NULL
FOR XML PATH(''), TYPE).value('text()[1]', 'NVARCHAR(MAX)'), 1, 1, '')
INSERT INTO #temp (DB, [COUNT])
EXEC sys.sp_executesql #SQL
SELECT *
FROM #temp t
Output (for example, in AdventureWorks) -
COUNT DB
----------- --------------------------------------------------
19972 AdventureWorks2008R2
19975 AdventureWorks2012
19472 AdventureWorks2008R2_Live
Straight forward query
EXECUTE sp_MSForEachDB
'USE ?; SELECT DB_NAME()AS DBName,
COUNT(1)AS [Count] FROM CUSTOMERS'
This query will show you what you want to see, but will also throw errors for each DB without a table called "CUSTOMERS". You will need to work out a logic to handle that.
Raj
How about something like this:
DECLARE c_db_names CURSOR FOR
SELECT name
FROM sys.databases
WHERE name NOT IN('master', 'tempdb') --might need to exclude more dbs
OPEN c_db_names
FETCH c_db_names INTO #db_name
WHILE ##Fetch_Status = 0
BEGIN
EXEC('
INSERT INTO #report
SELECT
''' + #db_name + '''
,COUNT(*)
FROM ' + #db_name + '..linkfile
')
FETCH c_db_names INTO #db_name
END
CLOSE c_db_names
DEALLOCATE c_db_names
SELECT * FROM #report
declare #userdb_list table (name varchar(4000) not null);
-- fill the db list with custom subset
insert into #userdb_list
select name from sys.databases --can add where condition to filter db names
declare
#curr_userdb varchar(300),
#db_placeholder varchar(300),
#final_db_exec_query varchar(max),
#query varchar(max);
set #query = '' -- <add ur query here>
set #db_placeholder = 'use {db}';
set #curr_userdb = (select min(name) from #userdb_list);
while #curr_userdb is not null
begin
set #final_db_exec_query = replace(#db_placeholder, '{db}', #curr_userdb + ' ' + #query);
exec (#final_db_exec_query);
--print #final_db_exec_query
set #curr_userdb = (select min(name) from #userdb_list where name > #curr_userdb);
end
GO
Solution without cursor - clean and simple
Because I know that a question was just referred to here that asked a slightly different question... if you only want to execute on certain databases, those databases could be stored in some table. Here I stored in a temporary table.
CREATE TABLE #Databases (
DbName varchar(255))
INSERT INTO #Databases (DbName)
Values ('GIS_NewJersey'), ('GIS_Pennsylvania')
DECLARE #command varchar(1000)
SELECT #command = 'Use [' + DbName + '];
Update sde.SAP_Load
SET FullAddress = CONCAT_WS('','', HouseNumber, Street, City, Postal, RegionName)
Update sde.PREMISE
SET FullAddress = CONCAT_WS('', '', HouseNumber, Street, City, Postal, RegionName)
Update sde.PREMISE_GEOCODE
SET FullAddress = CONCAT_WS('', '', HouseNumber, Street, City, Postal, RegionName)'
FROM #Databases
EXEC #command
I want to make full database backup of my server's all databases with unique name daily. For that I have an idea to keep timestamp which will make database copy separate.
Suppose there is a database on server named ABCD then it should be backuped like:
ABCD_21_03_2013
ABCD_22_03_2013
How can I do this. I don't know much about these types of SQL Backup JOBS.
To create a daily backup with a name such as Filename_MM_DD_YYYY:
In SSMS, right-click the database you want to backup
Select Tasks | Back Up
In the dialog, select the type and location of the backup
At the top of this dialog, select the Script Action to Job option in the Script drop down menu
A New Job dialog is opened and the first step creates a database backup
Go to the fist step and click Edit
Existing code looks like:
BACKUP DATABASE [AdventureWorks2012] TO DISK = N'E:\Test\AdventureWorks.bak' WITH NOFORMAT, NOINIT, NAME = N'AdventureWorks2012-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10
GO
Replace it to be
DECLARE #SQLStatement VARCHAR(2000)
SET #SQLStatement = 'E:\Test\AdventureWorks_' + CONVERT(nvarchar(30), GETDATE(), 110) +'.bak'
BACKUP DATABASE [AdventureWorks2012] TO DISK = #SQLStatement
6 Save the job
The database backups will be named:
AdventureWorks_07-29-2013
AdventureWorks_07-30-2013
AdventureWorks_07-31-2013
Now all you have to do is make the right schedule
Automatic backup of all databases on the server.
About Jobs:
http://msdn.microsoft.com/en-us/library/ms190268.aspx
Query:
SET NOCOUNT ON;
DECLARE
#FileName NVARCHAR(1024)
, #DBName NVARCHAR(256)
, #PathName NVARCHAR(256)
, #Message NVARCHAR(2048)
, #IsCompressed BIT
SELECT
#PathName = 'D:\BACKUP\'
, #IsCompressed = 1
DECLARE db CURSOR LOCAL READ_ONLY FAST_FORWARD FOR
SELECT
sd.name
, file_path = #PathName + FileDate + '_' + name + '.bak'
FROM sys.databases sd
CROSS JOIN (
SELECT FileDate = 'ABCD_' + REPLACE(CONVERT(VARCHAR(10), GETDATE(), 103), '/', '_')
) fd
WHERE sd.state_desc != 'OFFLINE'
AND sd.name NOT IN ('master', 'model', 'msdb', 'tempdb')
ORDER BY sd.name
OPEN db
FETCH NEXT FROM db INTO
#DBName
, #FileName
WHILE ##FETCH_STATUS = 0 BEGIN
DECLARE #SQL NVARCHAR(MAX)
SELECT #Message = REPLICATE('-', 80) + CHAR(13) + CONVERT(VARCHAR(20), GETDATE(), 120) + N': ' + #DBName
RAISERROR (#Message, 0, 1) WITH NOWAIT
SELECT #SQL =
'BACKUP DATABASE [' + #DBName + ']
TO DISK = N''' + #FileName + '''
WITH FORMAT, ' + CASE WHEN #IsCompressed = 1 THEN N'COMPRESSION, ' ELSE '' END + N'INIT, STATS = 15;'
EXEC sys.sp_executesql #SQL
FETCH NEXT FROM db INTO
#DBName
, #FileName
END
CLOSE db
DEALLOCATE db
Output:
BACKUP DATABASE [AdventureWorks2008R2]
TO DISK = N'D:\BACKUP\ABCD_24_05_2013_AdventureWorks2008R2.bak'
WITH FORMAT, COMPRESSION, INIT, STATS = 15;
BACKUP DATABASE [AdventureWorks2008R2_Live]
TO DISK = N'D:\BACKUP\ABCD_24_05_2013_AdventureWorks2008R2_Live.bak'
WITH FORMAT, COMPRESSION, INIT, STATS = 15;
BACKUP DATABASE [AdventureWorks2012]
TO DISK = N'D:\BACKUP\ABCD_24_05_2013_AdventureWorks2012.bak'
WITH FORMAT, COMPRESSION, INIT, STATS = 15;
Results:
2013-05-24 09:54:34: AdventureWorks2008R2
15 percent processed.
30 percent processed.
45 percent processed.
60 percent processed.
75 percent processed.
90 percent processed.
Processed 23416 pages for database 'AdventureWorks2008R2', file 'AdventureWorks2008R2_Data' on file 1.
Processed 1 pages for database 'AdventureWorks2008R2', file 'AdventureWorks2008R2_Log' on file 1.
BACKUP DATABASE successfully processed 23417 pages in 4.052 seconds (45.148 MB/sec).
.....
I think, best way to perform schedule back-up is to create Job. Add your back-up job and schedule that on particular date and time.
How to create job
Some third-party backup programs, for example: EMS SQL Backup, allow setting templates for backup file names. Timestamp, server instance name, database names and other info can be added to file name.
Thanks for the posts
I just want to share a small update I have made on the script to make log database backups and automatically skip all databases with recovery model = simple which does not allow log backups. Hope it helps...
And yes, Mr. Ravi is right the best approach is to create a job, I've created a SP and am running from a job.
CREATE PROCEDURE sp_logbackup
AS
SET NOCOUNT ON;
DECLARE
#FileName NVARCHAR(1024)
, #DBName NVARCHAR(256)
, #PathName NVARCHAR(256)
, #Message NVARCHAR(2048)
, #IsCompressed BIT
SELECT
#PathName = '\\myServer\...'
, #IsCompressed = 1
DECLARE db CURSOR LOCAL READ_ONLY FAST_FORWARD FOR
SELECT
sd.name
, file_path = #PathName + name + '_' + FileDate + '.trn'
FROM sys.databases sd
CROSS JOIN (
SELECT FileDate = REPLACE(REPLACE(REPLACE(CONVERT(varchar,GETDATE(), 20),'-','_'),':',''),' ','')
) fd
WHERE sd.state_desc != 'OFFLINE'
AND sd.recovery_model != 3
AND sd.name NOT IN ('master', 'model', 'msdb', 'tempdb')
ORDER BY sd.name
OPEN db
FETCH NEXT FROM db INTO
#DBName
, #FileName
WHILE ##FETCH_STATUS = 0 BEGIN
DECLARE #SQL NVARCHAR(MAX)
SELECT #Message = REPLICATE('-', 80) + CHAR(13) + CONVERT(VARCHAR(20), GETDATE(), 120) + N': ' + #DBName
RAISERROR (#Message, 0, 1) WITH NOWAIT
SELECT #SQL =
'BACKUP LOG [' + #DBName + ']
TO DISK = N''' + #FileName + '''
WITH FORMAT, NAME = N''' + #DBName + ''', SKIP, REWIND, NOUNLOAD, STATS = 10;'
EXEC sys.sp_executesql #SQL
FETCH NEXT FROM db INTO
#DBName
, #FileName
END
CLOSE db
DEALLOCATE db
I'm trying to shrink all databases (files and logs) in SQL Server 2008 R2.
I have finished the script, but the problem is that when I loop over all databases and execute the query to do shrink file the first 3 or 4 shrinks work but them I have this error :
Msg 0, Level 11, State 0, Line 0
A severe error occurred on the current command. The results, if any,
should be discarded.
The script :
declare #db_name as varchar(30)
declare #db_recorvery_model as varchar(30)
declare #db_files_name as varchar(250)
declare #db_files_physical_name as varchar(250)
declare get_files cursor for
select b.name, a.name
from sys.master_files as a,
sys.databases as b
where a.database_id = b.database_id
order by b.name
open get_files
fetch next from get_files into #db_files_name, #db_files_physical_name
set #db_files_name = (select #db_files_name)
set #db_files_physical_name = (select #db_files_physical_name)
DECLARE #Command as nvarchar(max)
set #Command=''
while(##FETCH_STATUS=0)
BEGIN
if (#db_files_name='master' or #db_files_name='msdb' or #db_files_name='tempdb' or #db_files_name='model')
BEGIN
print 'Bases de dados do sql server: '+#db_files_name
END
ELSE
BEGIN
set #Command = 'USE ' + '[' + #db_files_name + '] DBCC SHRINKFILE ("'+#db_files_physical_name+'", 1 )'
EXEC sp_executesql #Command
print #Command
END
fetch next from get_files into #db_files_name, #db_files_physical_name
set #db_files_name = (select #db_files_name)
set #db_files_physical_name = (select #db_files_physical_name)
END
close get_files
deallocate get_files
Does anyone have any ideas ?
PS: I know that I shouldn't shrink but is a very special environment and not productive.
Can you determine which database flags the error? Can you try running your script on the single database that has the problem and see if it is consistently the same database that triggers the error? Perhaps it's a special database that you've missed that cannot be shrunk that way.
I have a similar environment containing temp databases that are not for long term storage, and I use the following script which has worked perfectly for hundreds of databases:
CREATE procedure [dbo].[ShrinkLog]
#DB varchar(200)
as
declare #LogFile varchar(200)
declare #Sql varchar(500)
SELECT #LogFile = name
FROM sys.master_files
where type_desc = 'LOG'
and db_name(database_id) = #DB
set #Sql = '
Use [' + #DB + ']
DBCC SHRINKFILE([' + #LogFile + '], 1)
'
print(#sql)
exec(#sql)
Keep in mind also that you don't want to run this command unless your server has plenty of hard drive/memory space as well.
Best regards,
If you want to do a log shrink, this will be the best code. I am using it for a while and it never crash to me.
declare #SQL nvarchar(max)
select #SQL = coalesce(#SQL + char(13) + char(10),'') + N'
Use ' + QUOTENAME(d.[name]) + ';' + CHAR(13) + '
ALTER DATABASE ' + QUOTENAME(d.[name]) + ' SET RECOVERY SIMPLE;
DBCC SHRINKFILE (' + quotename(mf.[name],'''') + ', 1);
ALTER DATABASE ' + QUOTENAME(d.[name]) + ' SET RECOVERY FULL;'
FROM sys.databases d
INNER JOIN sys.master_files mf ON [d].[database_id] = [mf].[database_id]
WHERE
d.[database_id] > 4 --no sys dbs
AND d.recovery_model = 1
AND d.is_read_only = 0
AND mf.[type] = 1 --log files
ORDER BY d.name
--print #SQL
execute (#SQL)
I know the name of the table I want to find. I'm using Microsoft SQL Server Management Studio 2005, and I want to search all databases in the database server that I'm attached to in the studio. Is this possible? Do I need to query the system tables?
As above but use system function not system tables
EXEC sp_MSForEachDB 'USE [?] IF OBJECT_ID(''dbo.mytable'') IS NOT NULL PRINT ''?'''
You can use the sp_MSforeacheachdb.
sp_MSforeachdb 'IF EXISTS(SELECT * FROM sys.tables WHERE [Name] = ''TableName'') PRINT ''?''';
use master
DECLARE #db_name varchar(128)
DECLARE #DbID int
DECLARE #sql_string nvarchar(4000)
DECLARE #TableName varchar(30)
Select #TableName = ''
set nocount on
CREATE TABLE [#tblDatabaseName] (
[DbName] [varchar] (128) NOT NULL ,
[TableName] [varchar] (128) NOT NULL )
declare db_cursor cursor forward_only for
SELECT name, DbID
FROM master..sysdatabases
WHERE name NOT IN ('northwind', 'pubs')
AND (status & 32) <> 32 --loading.
AND (status & 64) <> 64 --pre recovery.
AND (status & 128) <> 128 --recovering.
AND (status & 256) <> 256 --not recovered.
AND (status & 512) <> 512 --Offline
AND (status & 32768) <> 32768 --emergency mode.
AND DbID > 4
open db_cursor
fetch next from db_cursor into #db_name, #DbID
while ##FETCH_STATUS = 0
begin
set #sql_string = ''
+' Insert into #tblDatabaseName '
+' select ''' + #db_name + ''' as ''DbName'', '
+' o.name as ''TableName'' '
+' from [' + #db_name + ']..sysobjects o with(nolock) '
+' where o.name like ''' + #TableName + ''' '
execute sp_executesql #sql_string
fetch next from db_cursor into #db_name, #DbID
end
deallocate db_cursor
select * from #tblDatabaseName
drop table #tblDatabaseName
sp_MSForEachDB is an undocumented proc that could do this for you. Getting the output out is a little harder so I'll leave that for you.
EXEC sp_MSForEachDB 'USE [?] IF EXISTS(SELECT * FROM Sys.Objects WHERE Type = ''U'' AND Name = ''Product'') PRINT ''?'''