Желаете наблюдать хранимые процедуры, которые существуют в нескольких базах данных и на нескольких серверах - PullRequest
1 голос
/ 25 мая 2011

Возникла проблема на нескольких серверах MS SQL 2005 Enterprise, где я хочу получить коллекцию метаданных на нескольких серверах и нескольких базах данных.В Stack Overflow я видел хороший пример использования магического sp_MSforeachdb, который я немного изменил ниже.По сути, хранимая процедура MS запускается динамически, и она ищет в любое время, когда база данных (?) Похожа на имя типа 'Case (fourspaces)'.Это здорово, и это дает мне то, что я хочу, но только для одного сервера.Я хочу сделать это для большего, возможно ли SQL-гуру?

Пример до сих пор:

SET NOCOUNT ON
DECLARE @AllTables table (CompleteTableName varchar(256))
INSERT INTO @AllTables (CompleteTableName)
    EXEC sp_msforeachdb 'select distinct @@SERVERNAME+''.''+ ''?'' + ''.'' + p.name from [?].sys.procedures p (nolock) where ''?'' like ''Case____'''
SELECT * FROM @AllTables ORDER BY 1

Есть ли способ сделать это в SQL, Linq или ADO.NETчтобы выполнить эту умную встроенную хранимую процедуру, которая вставляет переменную таблицы, чтобы сделать это несколько раз на разных серверах, НО ...... Поместите это в один набор.Насколько я знаю, вы НЕ МОЖЕТЕ переключать серверы в одном сеансе в SQL Management Studio, но мне бы очень хотелось, чтобы в этом я ошибался.

EG: у меня есть производственная среда с 8 серверами, каждый из которыхимеет много баз данных.Я мог запустить это несколько раз, но я надеялся, что, если серверы уже были связаны, я мог бы сделать это как-нибудь из системного представления.Однако я нахожусь в среде, использующей SQL 2005 и получил загрузку MS для представлений sys, и похоже, что sys.servers находится на острове, где SERVERID, кажется, не присоединяется ни к чему другому.

Iхотел бы использовать устройство чтения ADO.NET или LINQ в среде C # и, возможно, несколько раз вызвать вышеуказанный код TSQL, но ...... Есть ли более эффективный способ получения информации непосредственно в TSQL, ЕСЛИ серверы связаныСЕРВЕРЫ?Просто любопытно.

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

Любая помощь очень ценится, и если вам нужны дополнительные разъяснения, пожалуйста, спросите.

1 Ответ

0 голосов
/ 02 июня 2011

Я понял, что после настройки связанных серверов вы можете просто расширить имя связанного сервера слева от объекта, чтобы квалифицировать его более четко.

EG вместо sp_msforeachdb я могу сделать (имя сервера) .MASTER..sp_msforeachdb. Затем я могу перебрать свои серверы, если они связаны (они в моем случае) из таблицы sys.servers.

Я сделал некоторые вещи, которые замедлили бы работу с моим левым соединением, и что я сохраняю все сразу, а затем проверяю с помощью оператора «like» вместо явного квалификатора. Но в целом я думаю, что это решение предоставит конечному пользователю гибкость, чтобы не знать точное имя объекта, на который нужно охотиться. Мне также нравится, что теперь я могу использовать это с SSIS, SSRS и ADO.NET, поскольку процедура может выполнять итерацию для меня, и мне не нужно что-то делать в памяти приложений, а на сервере SQL. Я уверен, что у других могут быть лучшие идеи, но я ничего не слышал, так что это мое:

Полное решение ниже:

Create PROC [PE].[DeployChecker]
    (
        @DB     VARCHAR(128)
    ,   @Proc   VARCHAR(128) 
    )

AS 
    BEGIN 

    --declare variable for dynamic SQL
    DECLARE 
        @SQL    VARCHAR(512)
    ,   @x      int

    -- remove temp table if it exists as it should not be prepopulated.
    IF object_ID('tempdb..#Procs') IS NOT NULL
        DROP TABLE tempdb..#Procs

    -- Create temp table to catch built in sql stored procedure
    CREATE TABLE #Procs --DECLARE @Procs table 
        (
            ServerName      varchar(64)
        ,   DatabaseName    VARCHAR(128)
        ,   ObjectName      VARCHAR(256)
        )

    SET @X = 1

    -- Loops through the linked servers with matching criteria to examine how MANY there are.  Do a while loop while they exist.
    -- in our case the different servers are merely incrementing numbers so I merely do a while loop, you could be more explicit if needed.
    WHILE @X <= (SELECT count(*) FROM sys.servers WHERE name LIKE 'PCTRSQL_')
    BEGIN
        -- for some reason I can't automate the 'sp_msforeachdb' proc to take dynamic sql but I can set a variable to do it and then run it.
        SET @SQL = 'Insert Into #Procs Exec PCTRSQL' + CAST(@X AS VARCHAR(2)) + '.MASTER..sp_msforeachdb ' +
        '''select @@SERVERNAME, ''''?'''', name from [?].sys.procedures (nolock) where ''''?'''' like ''''%' + @DB + '%'''' '''

        Exec (@SQL)

        SET @X = @X + 1
    END
    ;

    -- Find distinct Server detail 
    WITH s AS 
        (
        SELECT Distinct
            ServerName
        ,   DatabaseName
        FROM #Procs 
        )
    -- do logic search in the select statement to see if there is a proc like what is searched for
    , p AS
        (
        SELECT 
            ServerName
        ,   DatabaseName
        ,   CASE WHEN ObjectName LIKE '%' + @Proc + '%' THEN ObjectName END AS ProcName
        FROM #Procs
        where  ObjectName LIKE '%' + @Proc + '%'
        )
    --  now do a left join from the distinct server cte to the lookup for the proc cte, we want to examine ALL the procs that match a critera
    --  however if nothing eixsts we wish to show a NULL value of a single row for a reference to the Servername and Database

    SELECT 
        s.ServerName
    ,   s.DatabaseName
    ,   p.ProcName
    ,   CAST(CASE WHEN ProcName IS NOT NULL THEN 1 ELSE 0 END AS bit) AS ExistsInDB
    FROM s
        LEFT JOIN p ON s.ServerName = p.ServerName 
            AND s.DatabaseName = p.DatabaseName
        ORDER BY DatabaseName, ServerName, ProcName

END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...