T-SQL谜题-爬行对象依赖项

T-SQL谜题-爬行对象依赖项,sql,sql-server,tsql,recursion,Sql,Sql Server,Tsql,Recursion,这段代码涉及一个递归存储过程调用和一个避免游标名称冲突的“不太好”方法。最后,我不在乎它是否使用游标。只是在寻找最优雅的方法。我主要将它用作跟踪存储过程层次结构的简单方法(无需购买产品)。我在“动态sql”中尝试了游标,但运气不太好。我想深入10层 所需输出: sp_Master_Proc_Name -- sp_Child_Proc_1_Name ---- sp_Sub_Proc_1_Name -- sp_Child_Proc_2_Name -- sp_Child_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
有关按深度对查询表外键依赖项进行排序的讨论,请参阅,这与您正在讨论的问题类似。答案中至少有两种有效的解决方案,与你所做的唯一真正不同的是它们正在爬行的表格。有一个DB反向工程脚本,该脚本显示了如何使用许多主数据字典表。

对于ms sql server,您可以使用游标本地,然后游标是存储过程调用的本地,您的代码变得更简单:

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

您正在使用SQL2005吗?如果是这样,您可能可以使用CTE在单个select语句中执行此操作。如果没有,您可能仍然可以使用临时表在单个非递归SP中执行此操作。只要继续抓住任何一排还剩下孩子的队伍就行了。如果明天我感冒好了,我会试着写点东西。酷,我想把这当作一个CTE。只是我。。。但是CTE让我的大脑比平时更痛。这只是另一种想法。在Stackoverflow上协作编写代码非常酷!我希望这个网站是10年前我刚开始的时候。呵呵。。。看起来NCX的链接实际上有我想的两个答案:weet!这是我在光标碰撞之前所做的(好吧,减去local关键字)。不知道有本地关键字。明天我将把它合并到我的代码中并试用。@[Bruno Tyndall]:还有另外一个关键字forward\u only或fast\u foward或类似的东西,您可能也应该将其用作优化。谢谢,这将帮助我解决一些T-SQL问题。
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