You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server视图依赖增强:关联填充表的存储过程

问题描述

我参考Stack Overflow上的一篇帖子调整逻辑后,实现了展示所有视图及其依赖表/视图的层级查询,能正确呈现视图间的依赖层级。现在希望增强功能:当视图依赖某张表时,将填充该表的存储过程也纳入现有层级体系中。目前能手动实现这个功能,但不知道如何整合到已有的层级查询里,求可行方案。

当前查询结果

![当前结果]

期望实现效果

![增强效果]

现有代码

-- 以下逻辑列出所有视图及其依赖的表
;with ObjectHierarchy ( Base_Object_Id , Base_Cchema_Id , Base_Object_Name , Base_Object_Type, object_id , Schema_Id , Name , Type_Desc , Level , Obj_Path) 
as 
    ( select  so.object_id as Base_Object_Id 
        , so.schema_id as Base_Cchema_Id 
        , so.name as Base_Object_Name 
        , so.type_desc as Base_Object_Type
        , so.object_id as object_id 
        , so.schema_id as Schema_Id 
        , so.name 
        , so.type_desc 
        , 0 as Level 
        , convert ( nvarchar ( 1000 ) , N'/' + so.name ) as Obj_Path 
    from sys.objects so 
        left join sys.sql_expression_dependencies ed on ed.referenced_id = so.object_id 
        left join sys.objects rso on rso.object_id = ed.referencing_id 
    where --rso.type is null 
         so.type in ( 'P', 'V', 'IF', 'FN', 'TF' ) 

    union all 

    select   cp.Base_Object_Id as Base_Object_Id 
        , cp.Base_Cchema_Id 
        , cp.Base_Object_Name 
        , cp.Base_Object_Type
        , so.object_id as object_id 
        , so.schema_id as ID_Schema 
        , so.name 
        , so.type_desc 
        , Level + 1 as Level 
        , convert ( nvarchar ( 1000 ) , cp.Obj_Path + N'/' + so.name ) as Obj_Path 
    from sys.objects so 
        inner join sys.sql_expression_dependencies ed on ed.referenced_id = so.object_id 
        inner join sys.objects rso on rso.object_id = ed.referencing_id 
        inner join ObjectHierarchy as cp on rso.object_id = cp.object_id and rso.object_id <> so.object_id 
    where so.type in ( 'P', 'V', 'IF', 'FN', 'TF', 'U') 
        and ( rso.type is null or rso.type in ( 'P', 'V', 'IF', 'FN', 'TF', 'U' ) ) 
        and cp.Obj_Path not like '%/' + so.name + '/%' )   -- 防止层级循环


select  DISTINCT  Base_Object_Name 
    , Base_Object_Type
    , REPLICATE ( '   ' , Level ) + Name as Indented_Name 
    , SCHEMA_NAME ( Schema_Id ) + '.' + Name as object_id 
    , Type_Desc as Object_Type 
    , Level 
    , Obj_Path 
from ObjectHierarchy as p 
WHERE BASE_OBJECT_TYPE = 'VIEW'
order by Obj_Path;


-------  查询填充指定表的存储过程逻辑

SELECT QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' + QUOTENAME(OBJECT_NAME(object_id))
FROM   sys.sql_dependencies
WHERE  referenced_major_id = OBJECT_ID((SELECT DISTINCT object_id  FROM ObjectHierarchy))
       AND is_updated = 1
GROUP  BY object_id
解决方案

要将填充表的存储过程整合到现有层级中,核心思路是在递归CTE的union all分支里新增一个针对**用户表(U)**的关联逻辑,将更新该表的存储过程纳入层级结构,具体实现如下:

修改后的完整SQL代码

-- 增强版:视图依赖层级+填充表的存储过程
;with ObjectHierarchy ( Base_Object_Id , Base_Cchema_Id , Base_Object_Name , Base_Object_Type, object_id , Schema_Id , Name , Type_Desc , Level , Obj_Path) 
as 
    ( 
    -- 初始节点:仅从视图开始,简化初始条件
    select  so.object_id as Base_Object_Id 
        , so.schema_id as Base_Cchema_Id 
        , so.name as Base_Object_Name 
        , so.type_desc as Base_Object_Type
        , so.object_id as object_id 
        , so.schema_id as Schema_Id 
        , so.name 
        , so.type_desc 
        , 0 as Level 
        , convert ( nvarchar ( 1000 ) , N'/' + so.name ) as Obj_Path 
    from sys.objects so 
    where so.type = 'V'

    union all 

    -- 分支1:处理视图/对象依赖的表、视图、函数等原有逻辑
    select   cp.Base_Object_Id as Base_Object_Id 
        , cp.Base_Cchema_Id 
        , cp.Base_Object_Name 
        , cp.Base_Object_Type
        , so.object_id as object_id 
        , so.schema_id as Schema_Id 
        , so.name 
        , so.type_desc 
        , cp.Level + 1 as Level 
        , convert ( nvarchar ( 1000 ) , cp.Obj_Path + N'/' + so.name ) as Obj_Path 
    from sys.objects so 
        inner join sys.sql_expression_dependencies ed on ed.referencing_id = cp.object_id and ed.referenced_id = so.object_id
        inner join ObjectHierarchy as cp on cp.object_id <> so.object_id 
    where so.type in ( 'V', 'IF', 'FN', 'TF', 'U') 
        and cp.Obj_Path not like '%/' + so.name + '/%'

    union all

    -- 分支2:关联更新当前表的存储过程
    select  cp.Base_Object_Id as Base_Object_Id
        , cp.Base_Cchema_Id
        , cp.Base_Object_Name
        , cp.Base_Object_Type
        , proc_obj.object_id as object_id
        , proc_obj.schema_id as Schema_Id
        , proc_obj.name as Name
        , proc_obj.type_desc as Type_Desc
        , cp.Level + 1 as Level
        , convert(nvarchar(1000), cp.Obj_Path + N'/[填充表的存储过程]/' + proc_obj.name) as Obj_Path
    from ObjectHierarchy cp
        inner join sys.sql_dependencies dep on dep.referenced_major_id = cp.object_id
        inner join sys.objects proc_obj on proc_obj.object_id = dep.object_id
    where cp.Type_Desc = 'USER_TABLE' -- 仅针对表节点添加存储过程
        and proc_obj.type = 'P' -- 筛选存储过程
        and dep.is_updated = 1 -- 仅保留更新该表的存储过程
        and cp.Obj_Path not like '%/' + proc_obj.name + '/%' -- 避免循环
    )

select  DISTINCT  
    Base_Object_Name 
    , Base_Object_Type
    , REPLICATE ( '   ' , Level ) + Name as Indented_Name 
    , SCHEMA_NAME ( Schema_Id ) + '.' + Name as Full_Object_Name 
    , Type_Desc as Object_Type 
    , Level 
    , Obj_Path 
from ObjectHierarchy as p 
order by Obj_Path;

关键说明

  • 初始节点简化:直接从视图开始,过滤掉无关的初始对象,减少冗余数据。
  • 双递归分支:原有分支维持视图到依赖对象的层级关系,新增分支专门处理表与填充它的存储过程的关联,逻辑清晰。
  • 路径标识:在存储过程的层级路径中添加[填充表的存储过程]标记,明确存储过程的角色,便于区分普通依赖对象。
  • 循环防护:通过路径匹配确保存储过程不会被重复加入同一层级链路,避免递归循环。

内容的提问来源于stack exchange,提问作者tomfbsc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:31:02