T-SQL Puzzler - сканирование зависимостей объектов - PullRequest
2 голосов
/ 19 декабря 2008

Этот код включает в себя рекурсивный вызов хранимой процедуры и «не очень хороший» метод, позволяющий избежать конфликта имен курсоров. В конце концов мне все равно, использует ли он курсоры или нет. Просто ищу самый элегантный подход. В основном я собираюсь использовать его как простой метод для отслеживания иерархий Stored Proc (без покупки продукта). Я пробовал курсоры в «динамическом sql» и мне не повезло. Я хотел бы пройти около 10 уровней.

Желаемый вывод:

sp_Master_Proc_Name  
-- sp_Child_Proc_1_Name  
---- sp_Sub_Proc_1_Name    
-- sp_Child_Proc_2_Name  
-- sp_Child_Proc_3_Name

Это не красиво, но вот код (и он не сработал, как ожидалось)

    CREATE PROCEDURE SP_GET_DEPENDENCIES
    (
      @obj_name varchar(300),
      @level int
    )
    AS
    DECLARE @sub_obj_name varchar(300)
    IF @level = 1
      BEGIN
        PRINT @obj_name
      END

    IF @level = 1
      BEGIN 
        DECLARE the_cursor_1 CURSOR FOR 
            SELECT DISTINCT REPLICATE('--', @level) + ' ' + c.name FROM dbo.sysdepends a
              INNER JOIN dbo.sysobjects b ON a.id = b.id
              INNER JOIN dbo.sysobjects c ON a.depid = c.id
              WHERE b.name = @obj_name
        OPEN the_cursor_1
        SET @level = @level + 1
        FETCH NEXT FROM the_cursor_1 INTO @sub_obj_name 
        WHILE @@FETCH_STATUS = 0 
          BEGIN 
            PRINT @sub_obj_name
            EXEC SP_GET_DEPENDENCIES @sub_obj_name, @level 
            FETCH NEXT FROM the_cursor_1 INTO @sub_obj_name 
          END
        CLOSE the_cursor_1
        DEALLOCATE the_cursor_1
      END

    IF @level = 2
      BEGIN 
        DECLARE the_cursor_2 CURSOR FOR 
            SELECT DISTINCT REPLICATE('--', @level) + ' ' + c.name FROM dbo.sysdepends a
              INNER JOIN dbo.sysobjects b ON a.id = b.id
              INNER JOIN dbo.sysobjects c ON a.depid = c.id
              WHERE b.name = @obj_name
        OPEN the_cursor_2
        SET @level = @level + 1
        FETCH NEXT FROM the_cursor_2 INTO @sub_obj_name 
        WHILE @@FETCH_STATUS = 0 
          BEGIN 
            PRINT @sub_obj_name
            EXEC SP_GET_DEPENDENCIES @sub_obj_name, @level 
            FETCH NEXT FROM the_cursor_2 INTO @sub_obj_name 
          END
        CLOSE the_cursor_2
        DEALLOCATE the_cursor_2
      END

    IF @level = 3
      BEGIN 
        DECLARE the_cursor_3 CURSOR FOR 
            SELECT DISTINCT REPLICATE('--', @level) + ' ' + c.name FROM dbo.sysdepends a
              INNER JOIN dbo.sysobjects b ON a.id = b.id
              INNER JOIN dbo.sysobjects c ON a.depid = c.id
              WHERE b.name = @obj_name
        OPEN the_cursor_3
        SET @level = @level + 1
        FETCH NEXT FROM the_cursor_3 INTO @sub_obj_name 
        WHILE @@FETCH_STATUS = 0 
          BEGIN 
            PRINT @sub_obj_name
            EXEC SP_GET_DEPENDENCIES @sub_obj_name, @level 
            FETCH NEXT FROM the_cursor_3 INTO @sub_obj_name 
          END
        CLOSE the_cursor_3
        DEALLOCATE the_cursor_3
      END

Ответы [ 2 ]

6 голосов
/ 19 декабря 2008

для ms sql server вы можете использовать CURSOR LOCAL, тогда курсор будет локальным для вызова sproc, и ваш код станет намного проще:

CREATE PROCEDURE uspPrintDependencies
(
    @obj_name varchar(300),
    @level int
)
AS
SET NOCOUNT ON
DECLARE @sub_obj_name varchar(300)

if @level > 0 begin
    PRINT Replicate(' ',@level) + @obj_name
end
else begin
    PRINT @obj_name
end

DECLARE myCursor CURSOR LOCAL FOR 
    SELECT 
        DISTINCT c.name 
    FROM dbo.sysdepends a
        INNER JOIN dbo.sysobjects b ON a.id = b.id
        INNER JOIN dbo.sysobjects c ON a.depid = c.id
    WHERE b.name = @obj_name
OPEN myCursor
SET @level = @level + 1
FETCH NEXT FROM myCursor INTO @sub_obj_name 
WHILE @@FETCH_STATUS = 0 BEGIN 
    EXEC uspPrintDependencies @sub_obj_name, @level 
    FETCH NEXT FROM myCursor INTO @sub_obj_name 
END
CLOSE myCursor
DEALLOCATE myCursor
GO
3 голосов
/ 19 декабря 2008

См. в этом вопросе Stackoverflow , где обсуждается сортировка запросов внешних ключей таблицы по глубине - проблема, аналогичная обсуждаемой. В ответах есть как минимум два рабочих решения этой проблемы, и единственное реальное отличие от того, что вы делаете, - это таблицы, которые они сканируют. Эта публикация содержит сценарий обратного инжиниринга БД, который показывает, как использовать множество основных таблиц словаря данных.

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