AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 127613
Accepted
Fredric Shope
Fredric Shope
Asked: 2016-01-29 07:18:24 +0800 CST2016-01-29 07:18:24 +0800 CST 2016-01-29 07:18:24 +0800 CST

我怎样才能知道什么数据库/过程正在使用链接服务器?

  • 772

我有 3 台服务器,其中一台配置了指向另一台的链接服务器——我称之为服务器 A。服务器 A 有 100 多个用于各种目的的用户数据库。服务器 B 正在运行我们正在尝试消除的 SQL 2005。服务器 C 具有服务器 B 的一些数据库的副本,我们正在将应用程序从服务器 B 的数据库副本迁移到服务器 C。

当我在服务器 B 上时,我可以看到从服务器 A 到某个数据库的连接,但我不知道如何判断服务器 A 的哪些过程、任务或作业正在使用与服务器 B 的链接服务器连接。

为了停用服务器 B 上的数据库,我需要将服务器 A 的连接重新指向服务器 C 上的数据库;但为了做到这一点,我需要知道服务器 A 上的哪些过程、任务或作业正在使用该连接,以便可以更新它们。

有没有办法在不禁用链接服务器的情况下查看链接服务器上的依赖关系以查看开始失败的原因?

sql-server stored-procedures
  • 2 2 个回答
  • 11071 Views

2 个回答

  • Voted
  1. Best Answer
    Aaron Bertrand
    2016-01-29T07:33:29+08:002016-01-29T07:33:29+08:00

    好吧,您可以解析服务器 A 上的过程(只要它们未加密)和作业,以查找链接服务器的名称 - 但请记住,这些请求可以通过应用程序传入,来自 ad hoc SQL,动态构建等,所以这不会捕获所有内容。如果链接的服务器名称是可能在代码或注释中自然找到的常用术语,这也会产生误报。

    DECLARE @sql NVARCHAR(MAX) = N'', 
      @p NVARCHAR(MAX), 
      @linked_server SYSNAME = N'%linked_server_name%';
    
    SET @p = N' UNION ALL SELECT N''$db$'', s.name,
       o.name FROM $db$.sys.sql_modules AS p
       INNER JOIN $db$.sys.objects AS o
       ON p.[object_id] = o.[object_id]
       INNER JOIN $db$.sys.schemas AS s
       ON o.[schema_id] = s.[schema_id]
      WHERE p.definition LIKE @lsn';
    
    SELECT @sql = @sql + REPLACE(@p, N'$db$', QUOTENAME(name))
      FROM sys.databases; -- may want to filter out system dbs, offline, etc
    
    SET @sql = STUFF(@sql, 1, 11, N'') + N';';
    
    EXEC sys.sp_executesql @sql, N'@lsn SYSNAME', @linked_server;
    
    SELECT j.name FROM msdb.dbo.sysjobs AS j
      INNER JOIN msdb.dbo.sysjobsteps AS s
      ON j.job_id = s.job_id
      WHERE s.command LIKE @linked_server;
    

    当然,您可能需要先寻找同义词:

    DECLARE @sql NVARCHAR(MAX) = N'', 
      @p NVARCHAR(MAX), 
      @synonym_prefix SYSNAME = N'[linked_server_name].%';
    
    SET @p = N' UNION ALL SELECT N''$db$'', s.name, o.name
       FROM $db$.sys.synonyms AS o
       INNER JOIN $db$.sys.schemas AS s
       ON o.[schema_id] = s.[schema_id]
      WHERE s.base_object_name LIKE @spre';
    
    SELECT @sql = @sql + REPLACE(@p, N'$db$', QUOTENAME(name))
      FROM sys.databases; -- may want to filter out system dbs, offline, etc
    
    SET @sql = STUFF(@sql, 1, 11, N'') + N';';
    
    EXEC sys.sp_executesql @sql, N'@spre SYSNAME', @synonym_prefix;
    

    然后使用这些同义词名称而不是'linked_server_name'上面的。

    • 7
  2. Jonathan Fite
    2016-01-29T07:55:38+08:002016-01-29T07:55:38+08:00

    我使用我开发的这个脚本来帮助我查找链接服务器引用,但可以用来查找多个对象中的任何文本字符串。

    /*********************************
        Name: Text Searcher
        Author: Jonathan Fite
        Created: 1/16/2015
    
        Purpose: To enable one to more easily search for objects by an indicated string.
    
        Usage: 
            - Update the "Where To Search" section to turn on or off various sections.
            - Craft an insert statement to populate "@ObjectsToSearchFor" with the text you
                want to look for.  
            - Execute.
    
        NOTE: This works recursively (in a fashion).  The first execution gets just what you are
        looking for.  But if you execute it again without explicitly dropping the "#SearchResults" table
        then it will run again, but this time looking for references to the objects it found in the first pass.
    
        This is useful when you are trying to find out what is using a linked server.  So you get the name of the 
        linked server (and it's host name) and run a search on that.  It tells you a handful of objects.  You then run
        it again, but this time looking for those objects (say, in other stored procedures or in SSIS/Jobs).  
    
        CAUTION: If you want to use the recursive functionality, you will need to save off the results FIRST.  
    
            DROP TABLE #SearchResults
    
        -Linked Server Query (finds all references to linked servers as configured, as well as all variations
            that would allow for accessing a remote server without using a linked server.
    
            INSERT INTO @ObjectsToSearchFor
            (TextString)
            SELECT srvname FROM sys.sysservers WHERE srvname <> @@SERVERNAME 
            UNION
            SELECT datasource FROM sys.sysservers WHERE srvname <> @@SERVERNAME
            UNION
            SELECT srvnetname FROM sys.sysservers WHERE srvnetname <> @@SERVERNAME
            UNION
            SELECT 'OPENROWSET'
            UNION
            SELECT 'OPENQUERY'
            UNION 
            SELECT 'OPENDATASOURCE'
    
    
    **********************************/
    
    --To hide row counts and make the print statements easier to see.
    SET NOCOUNT ON
    
    /** Where To Search **/
    DECLARE @SearchSSIS BIT = 1
    DECLARE @SearchObjectNames BIT = 1
    DECLARE @SearchObjectDefinition BIT = 1
    DECLARE @SearchAgentJobs BIT = 1
    
    /** What are you looking for? **/
    DECLARE @ObjectsToSearchFor TABLE
        (
        TextString VARCHAR(200) NULL
        )
    
    INSERT INTO @ObjectsToSearchFor
    (TextString)
    SELECT srvname FROM sys.sysservers WHERE srvname <> @@SERVERNAME 
    UNION
    SELECT datasource FROM sys.sysservers WHERE srvname <> @@SERVERNAME
    UNION
    SELECT srvnetname FROM sys.sysservers WHERE srvnetname <> @@SERVERNAME
    UNION
    SELECT 'OPENROWSET'
    UNION
    SELECT 'OPENQUERY'
    UNION 
    SELECT 'OPENDATASOURCE'
    
    /*************************************************************************************************************************
        Shouldn't need to mess with anything below this line.
    **************************************************************************************************************************/
    
    /** Handle Recursion on #SearchResults.
        Remember to save your data first!
    
        If you don't want recursion, explitly drop #SearchResults between executions.
        **/
    IF OBJECT_ID('tempdb..#SearchResults') IS NOT NULL
    BEGIN
    
        DELETE FROM @ObjectsToSearchFor 
    
        --This allows for successive iterations to search for objects which reference objects which reference....
        INSERT INTO @ObjectsToSearchFor
        (TextString)
        SELECT DISTINCT ObjectName
        FROM #SearchResults 
        WHERE LocationFound IN ('sys.sql_modules')
            AND ObjectName IS NOT NULL 
    
        SET @SearchObjectNames = 0
    
        DROP TABLE #SearchResults 
    
    END
    
    CREATE TABLE #SearchResults
        (
        DatabaseName SYSNAME NULL
        , ObjectName SYSNAME NULL
        , LocationFound VARCHAR(100) NULL
        , MatchedOn VARCHAR(200) NULL
        , Misc VARCHAR(100) NULL
        )
    
    /** Various declarations to hold results. **/
    DECLARE @SearchTerm VARCHAR(200)
    DECLARE @DatabaseName SYSNAME
    DECLARE @Query NVARCHAR(4000)
    
    -- Loop through search terms.
    DECLARE curSearch CURSOR LOCAL STATIC FORWARD_ONLY
    FOR SELECT O.TextString
        FROM @ObjectsToSearchFor O
    
    OPEN curSearch
    
    FETCH NEXT FROM curSearch
    INTO @SearchTerm
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
    
        --Begin Searching.
        PRINT ('Looking for: ' + @SearchTerm)
    
        /** This will loop over every database, only do it if you need it. **/
        IF(@SearchObjectDefinition = 1 OR @SearchObjectNames = 1)
        BEGIN
    
            DECLARE curDatabases CURSOR LOCAL STATIC FORWARD_ONLY
            FOR SELECT D.name
                FROM sys.sysdatabases D
                ORDER BY D.name 
    
            OPEN curDatabases
    
            FETCH NEXT FROM curDatabases 
            INTO @DatabaseName 
    
            WHILE @@FETCH_STATUS = 0
            BEGIN
    
                --Look for object name matching...
                IF(@SearchObjectNames = 1)
                BEGIN
    
                    SET @Query = 'USE ' + QUOTENAME(@DatabaseName) + ';'
                        + 'INSERT INTO #SearchResults'
                        + ' SELECT DB_NAME()'
                        + ', O.name'
                        + ', ' + QUOTENAME('sys.objects', '''')
                        + ', ' + QUOTENAME(@SearchTerm, '''')
                        + ', O.type_desc'
                        + ' FROM sys.objects O (NOLOCK)'
                        + ' WHERE LOWER(O.name) LIKE ' + QUOTENAME('%' + LOWER(@SearchTerm) + '%', '''')
    
                    EXEC sp_executesql @Query 
    
                    SET @Query = 'USE ' + QUOTENAME(@DatabaseName) + ';'
                        + 'INSERT INTO #SearchResults'
                        + ' SELECT DB_NAME()'
                        + ', C.name'
                        + ', ' + QUOTENAME('sys.columns', '''')
                        + ', ' + QUOTENAME(@SearchTerm, '''')
                        + ', O.name + O.type_desc'
                        + ' FROM sys.columns C (NOLOCK) INNER JOIN sys.objects O ON O.[object_id] = C.[object_id]'
                        + ' WHERE LOWER(C.name) LIKE ' + QUOTENAME('%' + LOWER(@SearchTerm) + '%', '''')
    
                    EXEC sp_executesql @Query 
    
                END --Looking for object names.
    
                --Look for definitions.
                --Find objects that have the string in question listed, but ignore where the name is what is being searched for.
                IF(@SearchObjectDefinition = 1)
                BEGIN
    
                    SET @Query = 'USE ' + QUOTENAME(@DatabaseName) + ';'
                        + 'INSERT INTO #SearchResults'
                        + ' SELECT DB_NAME()'
                        + ', O.name'
                        + ', ' + QUOTENAME('sys.sql_modules', '''')
                        + ', ' + QUOTENAME(@SearchTerm, '''')
                        + ', O.type_desc'
                        + ' FROM sys.sql_modules M (NOLOCK) INNER JOIN sys.objects O ON O.[object_id] = M.[object_id]'
                        + ' WHERE LOWER(M.[definition]) LIKE ' + QUOTENAME('%' + LOWER(@SearchTerm) + '%', '''')
                        + ' AND NOT(LOWER(O.name) = LOWER(' + QUOTENAME(@SearchTerm, '''') + '))'
    
                    EXEC sp_executesql @Query 
    
                END --Looking for object definitions.
    
                --Get next database
                FETCH NEXT FROM curDatabases
                INTO @DatabaseName
    
            END
    
            CLOSE curDatabases
            DEALLOCATE curDatabases 
    
    
        END
    
        --Look in SSIS packages.
        IF(@SearchSSIS = 1)
        BEGIN
    
            ;WITH SSISFolders AS
            (
            SELECT pf.folderid
                , pf.parentfolderid
                , CAST(pf.foldername AS VARCHAR(MAX)) AS foldername
            FROM msdb.dbo.sysssispackagefolders pf (NOLOCK)
            WHERE pf.parentfolderid IS NULL 
            UNION ALL
            SELECT pf.folderid
                , pf.parentfolderid
                , Parent.foldername + '\' + ISNULL(CAST(pf.foldername AS VARCHAR(MAX)), '') AS foldername
            FROM msdb.dbo.sysssispackagefolders pf (NOLOCK)
                INNER JOIN SSISFolders Parent ON Parent.folderid = pf.parentfolderid 
            )
            INSERT INTO #SearchResults
            SELECT NULL
                , ISNULL(F.foldername, '') + '\' + CAST(ISNULL(S.name, '') AS VARCHAR(MAX))
                , 'msdb.dbo.syssispackages'
                , @SearchTerm
                , NULL 
            FROM msdb.dbo.sysssispackages S (NOLOCK)
                LEFT OUTER JOIN SSISFolders F (NOLOCK) ON F.folderid = S.folderid 
            WHERE LOWER(CAST(CAST(CAST(CAST(packagedata AS VARBINARY(MAX)) AS VARCHAR(MAX)) AS XML) AS VARCHAR(MAX))) LIKE ('%' + @SearchTerm + '%')
    
        END
    
        --Look in SQL Agent Jobs
        IF(@SearchAgentJobs = 1)
        BEGIN
    
            --Job Name
            INSERT INTO #SearchResults
            SELECT NULL
                , J.name
                , 'msdb.dbo.sysjobs'
                , @SearchTerm
                , 'Job Name'
            FROM msdb.dbo.sysjobs J (NOLOCK)
            WHERE LOWER(J.name) LIKE ('%' + @SearchTerm + '%')
    
            --Job Description
            INSERT INTO #SearchResults
            SELECT NULL
                , J.name
                , 'msdb.dbo.sysjobs'
                , @SearchTerm
                , 'Job Description'
            FROM msdb.dbo.sysjobs J (NOLOCK)
            WHERE LOWER(J.[description]) LIKE ('%' + @SearchTerm + '%')
    
            --Step Name.
            INSERT INTO #SearchResults
            SELECT NULL
                , (ISNULL(J.name, '') + ' - ' + ISNULL(S.step_name, '') + ' (' + CAST(S.step_id AS VARCHAR(10)) + ')')
                , 'msdb.dbo.sysjobsteps'
                , @SearchTerm 
                , 'Step Name'
            FROM msdb.dbo.sysjobsteps S (NOLOCK)
                INNER JOIN msdb.dbo.sysjobs J (NOLOCK) ON J.job_id = S.job_id
            WHERE LOWER(S.step_name) LIKE ('%' + @SearchTerm + '%')
    
            --Step Code.
    
            INSERT INTO #SearchResults
            SELECT NULL
                , (ISNULL(J.name, '') + ' - ' + ISNULL(S.step_name, '') + ' (' + CAST(S.step_id AS VARCHAR(10)) + ')')
                , 'msdb.dbo.sysjobsteps'
                , @SearchTerm 
                , 'Step Code'
            FROM msdb.dbo.sysjobsteps S (NOLOCK)
                INNER JOIN msdb.dbo.sysjobs J (NOLOCK) ON J.job_id = S.job_id
            WHERE LOWER(S.command) LIKE ('%' + @SearchTerm + '%')
    
        END --End Looking at Jobs.
    
        --Get next search term.
        FETCH NEXT FROM curSearch
        INTO @SearchTerm
    
    END
    
    --Cleanup.
    CLOSE curSearch
    DEALLOCATE curSearch 
    
    
    /***************** Display Output **********************************/
    
    --Display search terms.
    SELECT O.TextString
        , COUNT(S.MatchedOn) AS MatchCount 
    FROM @ObjectsToSearchFor O
        LEFT OUTER JOIN #SearchResults S ON S.MatchedOn = O.TextString
    GROUP BY O.TextString 
    
    --Display search results.
    SELECT DISTINCT * FROM #SearchResults 
    
    • 5

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve