希望观察存在于多个数据库和多个服务器上的存储过程

问题描述

|| 在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台服务器,每台服务器都有许多数据库。我可以运行多次,但我希望如果服务器已经链接,则可以通过sys视图执行此操作。但是,我在使用SQL 2005的环境中,并获得了MS \的sys视图下载,并且看起来sys.servers本身就位于一个孤岛上,其中SERVERID似乎未加入任何其他内容。 我愿意在C#环境中使用ADO.NET阅读器或LINQ,并可能多次调用上面的TSQL代码,但是......如果服务器位于TSQL,是否有更有效的方法直接在TSQL中获取信息链接服务器?只是好奇。 此操作的总体目的是出于部署目的,以查看所有服务器和数据库中存在多少个过程。现在我们确实有来自Redgate的SQL比较,但是我不知道它是否可以编写与set A相同的不存在的proc脚本。即使可行,我也想尝试自己动手做一些事情。 非常感谢您的帮助,如果您需要进一步的说明,请询问。     

解决方法

我弄清楚了,一旦设置了链接服务器,您就只能将链接服务器名称扩展到对象的左侧,以更明确地限定其名称。 我可以用EG代替sp_msforeachdb(服务器名).MASTER..sp_msforeachdb。然后,如果从sys.servers表中链接了服务器(在我的情况下为链接服务器),则可以遍历服务器。 我做了一些事情,这些事情会使我的左联接放慢速度,并立即存储所有内容,然后使用\'like \'语句(而不是显式的限定词)进行检查。但是总的来说,我认为该解决方案将为最终用户提供灵活性,使其无需知道要寻找的对象的确切名称。我也喜欢我现在可以将其与SSIS,SSRS和ADO.NET一起使用,因为该过程可以为我执行狩猎迭代,并且我不必在应用程序内存中执行任何操作,而可以在SQL Server上执行某些操作。我确定其他人可能有更好的主意,但是我什么也没听到,所以这是我的: 完整的解决方案如下:
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
    

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...