Необходимо запустить хранимую процедуру на всех не системных базах данных - PullRequest
0 голосов
/ 30 мая 2019

Я пытаюсь перебрать все несистемные базы данных и запустить хранимую процедуру.Эта хранимая процедура существует во всех пользовательских базах данных.

Это то, что я нашел до сих пор:

DECLARE @command varchar(1000) 
SELECT @command = 'USE ? SELECT name FROM sysobjects WHERE xtype = ''U'' ORDER BY name' 

USE @command;
GO

EXECUTE Support.CleanIndiciesAndShrinkDatabase;
GO

Я получаю сообщение об ошибке:

Сообщение 102, уровень 15, состояние 1, строка 3
Неверный синтаксис рядом с'@command'.

Сообщение 2812, уровень 16, состояние 62, строка 1
Не удалось найти хранимую процедуру 'Поддержка.CleanIndiciesAndShrinkDatabase '.

Есть предложения по исправлению?

Ответы [ 3 ]

1 голос
/ 30 мая 2019

Попробуйте следующее


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

Он будет работать на всех несистемных базах данных.Теперь ошибка, которую вы получаете, означает, что SQL Server не может найти хранимую процедуру.Вы можете исправить это, создав хранимую процедуру в любой базе данных, которая еще не имеет ее, а затем запустив ее.Так что лучше запрос будет


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



0 голосов
/ 30 мая 2019

Вы можете попробовать это:

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
0 голосов
/ 30 мая 2019

Попробуйте что-то вроде этого:

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;
...