Reputation: 347
I'm trying to loop through all non system databases and run a stored procedure. This stored procedure exists in all of the user databases.
This is what I have found so far:
DECLARE @command varchar(1000)
SELECT @command = 'USE ? SELECT name FROM sysobjects WHERE xtype = ''U'' ORDER BY name'
USE @command;
GO
EXECUTE Support.CleanIndiciesAndShrinkDatabase;
GO
I get an error this error:
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near '@command'.Msg 2812, Level 16, State 62, Line 1
Could not find stored procedure 'Support.CleanIndiciesAndShrinkDatabase'.
Any suggestions on fixing this?
Upvotes: 0
Views: 366
Reputation: 43666
Try something like this:
DECLARE @DynamicTSQLStatement NVARCHAR(MAX);
SELECT @DynamicTSQLStatement = STUFF
(
(
SELECT 'USE [' + [name] + ']; EXECUTE Support.CleanIndiciesAndShrinkDatabase;'
FROM [sys].[databases]
WHERE [name] NOT IN ('master', 'tempdb', 'model', 'msdb')
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,1
,''
);
EXECUTE sp_executesql @DynamicTSQLStatement;
Upvotes: 0
Reputation: 2403
You can try this:
Create PROC PROC_NAME
AS
BEGIN
DECLARE @name nvarchar(50)
declare @cursor cursor
set @cursor = CURSOR FAST_FORWARD FOR select name from sys.databases where database_id > 4
open @cursor
FETCH NEXT FROM @cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @use nvarchar(50) = 'USE '
SET @use = @use + @name
Declare @query nvarchar(max) = @use + ' exec Your_PROC'
EXEC sp_executesql @query
FETCH NEXT FROM @cursor INTO @name
END
CLOSE @cursor
DEALLOCATE @cursor
END
Upvotes: 0
Reputation: 89
Try the following
DECLARE @command varchar(1000)
DECLARE @spName VARCHAR(50)
SET @spName = 'Support.CleanIndiciesAndShrinkDatabase'
SELECT @command = 'IF ''?'' NOT IN(''master'', ''model'', ''msdb'', ''tempdb'')
BEGIN
USE ?
IF EXISTS(SELECT TOP 1 1 FROM sys.procedures AS P WHERE p.name = ''' + @spName + ''')
BEGIN
PRINT ''running '+ @spName + ' on '' + DB_NAME()
EXEC ' +@spName+'
END
ELSE
BEGIN
PRINT ''' + @spName + ' was on found on database '' + DB_NAME()''
END
END '
EXEC sp_MSforeachdb @command
It will run on all non-system databases. Now, the error you get means that SQL Server cannot find the stored procedure. You could fix this by creating the stored procedure on any database that does not have it yet and then running it. So a better query would be
DECLARE @command varchar(1000)
DECLARE @schemaName VARCHAR(50)
DECLARE @spName VARCHAR(50)
SET @schemaName = 'Support'
SET @spName = 'CleanIndiciesAndShrinkDatabase'
SELECT @command = 'IF ''?'' NOT IN(''master'', ''model'', ''msdb'', ''tempdb'')
BEGIN
USE ?
IF NOT EXISTS(SELECT TOP 1 1
FROM sys.procedures AS P
INNER JOIN sys.schemas AS S ON S.schema_id = P.schema_id
WHERE p.name = ''' + @spName + '''
AND s.name = ''' + @schemaName + ''')
BEGIN
PRINT ''creating '+ @spName + ' on '' + DB_NAME()
IF NOT EXISTS ( SELECT TOP 1 1
FROM sys.schemas AS S
WHERE S.name = ''' + @schemaName + ''' )
BEGIN
PRINT ''CREATING SCHEMA ' + @schemaName + '''
EXEC ( '' CREATE SCHEMA ' + @schemaName + ''' );
END;
EXEC ( ''
CREATE PROCEDURE ' + @schemaName + '.' + @spName + '
AS
BEGIN
-- SP CODE GOES HERE
-- SELECT COUNT(*) FROM SYS.TABLES --uncomment this for check
END
'' );
END
PRINT ''running '+ @spName + ' on '' + DB_NAME()
EXEC ' + @schemaName + '.' + @spName +'
END '
EXEC sp_MSforeachdb @command
Upvotes: 1