【问题标题】:SQL Server 2005 Stored Procedure DependenciesSQL Server 2005 存储过程依赖项
【发布时间】:2010-07-07 13:27:32
【问题描述】:

我有一个存储过程列表,我正在尝试确定它们应该执行的顺序。

有没有办法确定存储过程如何相互依赖。我在想我可以使用 sysobjects 和 syscmets。

谢谢

【问题讨论】:

    标签: sql-server sql-server-2005 stored-procedures


    【解决方案1】:

    一种方法是

    EXEC sp_depends 'your_procedure_name'
    

    【讨论】:

      【解决方案2】:

      这是一篇关于如何创建 UDF 来执行此操作的文章。它按照您的建议使用 sysobjects 和 syscmets 表。

      http://www.eggheadcafe.com/community/aspnet/13/12562/list-sql-stored-procedure.aspx

      这是 UDF 的 SQL:

      CREATE FUNCTION dbo.uf_FindProcedureDependencies(@ProcName varchar(256))
              RETURNS @blah TABLE (depth tinyint not null,
              tree varchar(7700) COLLATE SQL_Latin1_General_CP437_BIN not null,
              objectname varchar(256) COLLATE SQL_Latin1_General_CP437_BIN not null,
              dependencytype varchar(16) COLLATE SQL_Latin1_General_CP437_BIN not null)
      AS
      BEGIN
          DECLARE @depth tinyint
          SELECT @depth = 1
      
          INSERT @blah (depth, tree, objectname, dependencytype)
              SELECT DISTINCT @depth, @ProcName + ' -> ' + so2.name, so2.name, 'stored procedure' FROM 
                  sysobjects so1, syscomments sc1, sysobjects so2, syscomments sc2 WHERE
                  so1.id = sc1.id AND so2.id = sc2.id AND so1.id <> so2.id AND so1.type = 'P' AND so2.type = 'P'
                  AND so1.name = @ProcName AND REPLACE(sc1.text,so1.name,'') LIKE '%EXEC%' + so2.name + '%'
      
          WHILE (@@ROWCOUNT > 0)
          BEGIN
              SET @depth = @depth + 1
              INSERT @blah (depth, tree, objectname, dependencytype)
                  SELECT DISTINCT @depth, b.objectname + ' -> ' + so2.name, so2.name, 'stored procedure' FROM 
                  sysobjects so1, syscomments sc1, sysobjects so2, syscomments sc2, @blah b WHERE
                  so1.id = sc1.id AND so2.id = sc2.id AND so1.id <> so2.id AND so1.type = 'P' AND so2.type = 'P'
                  AND so1.name = b.objectname AND REPLACE(sc1.text,so1.name,'') LIKE '%EXEC%' + so2.name + '%'
                  AND b.depth = @depth - 1
          END
      
          RETURN
      END
      

      【讨论】:

        【解决方案3】:

        这是我几周前整理的一些代码,用于构建对象的顺序,以便根据它们的依赖关系应用于数据库。第一个存储过程只是刷新元数据,这样您就可以确定 sql_dependencies 是准确的。

        这不是经过全面测试的代码。另外,如果我再次这样做,我可能会使用 INFORMATION_SCHEMA 而不是直接针对系统表。

        run_level 告诉您何时可以创建每个对象。因此,所有 run_level 为 0 的对象都可以先运行(在 run_level 中顺序无关紧要),然后是 run_level 1 的所有对象,等等。

        IF (OBJECT_ID('dbo.RefreshSqlModuleForAllObjs') IS NOT NULL)
            DROP PROCEDURE dbo.RefreshSqlModuleForAllObjs
        GO
        CREATE PROCEDURE dbo.RefreshSqlModuleForAllObjs
        AS
        BEGIN
            DECLARE
                @object_id      INT,
                @schema_name    SYSNAME,
                @object_name    SYSNAME,
                @full_name      NVARCHAR(776)
        
            DECLARE cur_objects CURSOR FOR
                SELECT
                    object_id,
                    OBJECT_SCHEMA_NAME(object_id),
                    OBJECT_NAME(object_id)
                FROM
                    sys.objects
                WHERE
                    type IN ('P', 'TR', 'V', 'FN', 'TF', 'IF')
        
            OPEN cur_objects
        
            FETCH NEXT FROM cur_objects INTO @object_id, @schema_name, @object_name
        
            WHILE (@@FETCH_STATUS = 0)
            BEGIN
                SET @full_name = QUOTENAME(@schema_name) + '.' + QUOTENAME(@object_name)
        
                EXEC sp_refreshsqlmodule @full_name
        
                FETCH NEXT FROM cur_objects INTO @object_id, @schema_name, @object_name
            END
        
            CLOSE cur_objects
        
            DEALLOCATE cur_objects
        END
        GO
        

        IF (OBJECT_ID('dbo.GenObjApplyOrder') IS NOT NULL)
            DROP PROCEDURE dbo.GenObjApplyOrder
        GO
        CREATE PROCEDURE dbo.GenObjApplyOrder
        AS
        BEGIN
            DECLARE
                @i  INT,
                @count  INT
        
            DECLARE
                @run_order TABLE (object_id INT, run_level SMALLINT)
        
            SET @i = 0
            SET @count = 1
        
            EXEC dbo.RefreshSqlModuleForAllObjs
        
            WHILE (@count > 0)
            BEGIN
                INSERT INTO @run_order (object_id, run_level)
                SELECT
                    object_id,
                    @i
                FROM
                    sys.objects o
                WHERE
                    NOT EXISTS (SELECT * FROM sys.sql_dependencies d WHERE d.object_id = o.object_id AND d.referenced_major_id NOT IN (SELECT object_id FROM @run_order)) AND
                    NOT EXISTS (SELECT * FROM @run_order ro WHERE ro.object_id = o.object_id) AND
                    o.type IN ('U', 'P', 'V', 'TR', 'TF', 'IF', 'FN')
        
                SELECT @count = @@ROWCOUNT
        
                SELECT @i = @i + 1
            END
        
            INSERT INTO @run_order (object_id, run_level)
            SELECT
                o.object_id,
                -999
            FROM
                sys.objects o
            WHERE
                NOT EXISTS (SELECT * FROM @run_order ro WHERE ro.object_id = o.object_id) AND
                o.type IN ('U', 'P', 'V', 'TR', 'TF', 'IF', 'FN')
        
            SELECT OBJECT_NAME(object_id), run_level FROM @run_order ORDER BY ABS(run_level)
        END
        GO
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-18
          • 1970-01-01
          • 2011-03-12
          相关资源
          最近更新 更多