Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 希望观察存在于多个数据库和多个服务器上的存储过程_C#_Linq_Sql Server 2005_Tsql_Ado.net - Fatal编程技术网

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

C# 希望观察存在于多个数据库和多个服务器上的存储过程,c#,linq,sql-server-2005,tsql,ado.net,C#,Linq,Sql Server 2005,Tsql,Ado.net,MS SQL 2005 Enterprise multiple Server出现问题,我希望跨多个服务器和多个数据库获取元数据集合。我在Stack Overflow上看到了一个使用神奇的sp_MSforeachdb的好例子,我在下面稍微修改了一下。基本上,MS存储过程是动态运行的,它寻找数据库(?)像“Case(fourspaces)”这样的名称。这是伟大的,它给了我我想要的,但只有一个服务器。我想这样做更多,是否有可能成为SQL专家 迄今为止的例子: SET NOCOUNT ON DECLAR

MS SQL 2005 Enterprise multiple Server出现问题,我希望跨多个服务器和多个数据库获取元数据集合。我在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中,您不能在一个会话中切换服务器,但我希望在这个会话中被证明是错误的

我有一个有8台服务器的生产环境,每台服务器都有许多数据库。我可以运行多次,但我希望,如果服务器已经链接,我可以从sys视图以某种方式执行此操作。然而,我在一个使用SQL 2005的环境中,得到了MS下载的sys视图,它看起来像sys.servers位于一个孤岛上,其中SERVERID似乎没有加入任何其他内容

我愿意在C#环境中使用ADO.NET阅读器或LINQ,并可能多次调用上述TSQL代码,但是。。。。。。如果服务器是链接服务器,是否有更有效的方法直接在TSQL中获取信息?只是好奇

此操作的总体目的是为了部署,以查看所有服务器和数据库中存在多少过程。现在我们有了来自Redgate的SQL compare,但我不知道它是否可以将不存在的过程脚本化为与集合A相同的存在。即使可以,如果可行的话,我想尝试自己做一些事情


非常感谢您提供的任何帮助,如果您需要进一步的说明,请询问。

我知道了,一旦您设置了链接服务器,您只需将链接服务器名称扩展到对象的左侧,以更清楚地限定它

例如,我可以使用(Servername).MASTER..sp_msforeachdb代替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
Create PROC[PE].[DeployChecker]
(
@DB VARCHAR(128)
,@Proc VARCHAR(128)
)
作为
开始
--为动态SQL声明变量
声明
@SQL VARCHAR(512)
,@x int
--删除临时表(如果存在),因为不应预填充临时表。
如果对象_ID('tempdb..#Procs')不为空
删除表tempdb..#Procs
--创建临时表以捕获内置sql存储过程
创建表#Procs——声明@Procs表
(
ServerName varchar(64)
,数据库名VARCHAR(128)
,ObjectName VARCHAR(256)
)
设置@X=1
--使用匹配条件在链接的服务器中循环,以检查有多少个服务器。在它们存在时执行while循环。
--在我们的例子中,不同的服务器只是在增加数量,所以我只做了一个while循环,如果需要的话,您可以更加明确。

而@X如果我要重新表述您的问题:给定一个服务器列表,您希望能够对这些服务器上的所有(?)数据库运行一个查询,以查看它们有多少符合特定命名模式的存储过程(Case\uuuuuu)?关闭。我想对与数据库上的模式匹配的所有数据库(Case_u___;)运行一个查询,以便对所有过程或用户提示的搜索进行查询。最终,用户将执行一个输入,如exec spgetdeploystats@PROCEDURENAME,其中@PROCEDURENAME是要在所有服务器上查找的过程的名称。(很抱歉被愚弄的帖子,没有意识到enter会停止评论)