首页 > 数据库 >SQL Server如何找出视图依赖的对象和视图嵌套层数

SQL Server如何找出视图依赖的对象和视图嵌套层数

时间:2023-03-22 09:15:23浏览次数:58  
标签:referenced name object 视图 Server SQL id desc

场景:在SQL Server数据库的SQL优化中,我们有时候会需要找出某个视图的依赖对象,简单的视图倒是很容易一眼就找出依赖对象,一旦遇到一些复杂的视图,如果我们手动整理的话,就相当麻烦了,因为你要一个对象一个对象的捋一遍。相当的耗时耗力,其实这种机械、重复、繁杂的事情就应该让机器(SQL)去处理。我们应该将精力和时间用在关键的地方。所谓好钢要用在刀刃上。所以最好能用一个SQL将视图依赖的对象全部查询出来。下面是我写的一个脚本。

/*-*************************************************************************************************************
    --脚本名称  :      get_view_referenced_objects.sql
    --脚本作者  :       潇湘隐者
    --创建日期  :       2018-06-28
***************************************************************************************************************
    脚本功能    :       查看View引用/依赖的对象
***************************************************************************************************************
    注意事项    :       1:执行前修改参数@object_name的值
***************************************************************************************************************
    脚本参数    :       @object_name  按实际情况填写对应的视图名称
***************************************************************************************************************
    参考资料    :       无
***************************************************************************************************************
    更新记录    :      2018-06-28 创建此脚本
                       2022-01-06 修改脚本,如果被引用的对象不是跨数据库或跨服务器的对象,
                                   那么server_name,database_name为null,修改脚本逻辑。
*-**************************************************************************************************************/
declare @object_name varchar(128)
set @object_name = 'dbo.v_SecPolicyInfo'

;WITH cte_objects
AS
(
SELECT 1 as  nested_level
      ,d.referencing_id
      ,d.referenced_id
      ,d.referenced_server_name
      ,d.referenced_database_name
      ,d.referenced_class_desc
      ,d.referenced_schema_name
      ,d.referenced_entity_name
FROM sys.sql_expression_dependencies d
WHERE d.referencing_id = object_id(@object_name)
UNION ALL
SELECT t.nested_level+1 nested_level
      ,d.referencing_id
      ,d.referenced_id
      ,d.referenced_server_name
      ,d.referenced_database_name
      ,d.referenced_class_desc
      ,d.referenced_schema_name
      ,d.referenced_entity_name
FROM sys.sql_expression_dependencies d
INNER JOIN cte_objects t
   ON t.referenced_id = d.referencing_id
)

SELECT d.nested_level
     , schema_name(o.schema_id) +'.' + o.name as object_name
     , o.type_desc 
     , ISNULL(d.referenced_server_name,@@SERVERNAME) as referenced_server_name
     , ISNULL(d.referenced_database_name, DB_NAME()) as referenced_database_name
     , d.referenced_class_desc
     , ISNULL(d.referenced_schema_name,'dbo') 
       + '.' +d.referenced_entity_name as referenced_entity_name
     , p.type_desc as  referenced_object_type

FROM cte_objects d
INNER JOIN sys.objects o
    ON d.referencing_id = o.object_id
INNER JOIN sys.objects p
    ON d.referenced_id = p.object_id ;

场景:有时候,我们在数据库优化或做一些SQL审计的时候,我们需要找出一些嵌套的视图,那么有没有一个现成的SQL语句找出嵌套视图呢?我自己写过一个SQL,但是How to query metadata to discover nested views中的SQL比我写的要好,分享如下(下面脚本来源于参考资料):

/*-*************************************************************************************************************
    --脚本名称  :      get_netsted_view_level.sql
    --脚本作者  :       Fredrik Rundgren
    --创建日期  :       2018-04-15
***************************************************************************************************************
    脚本功能    :      找出数据库视图嵌套视图的视图/嵌套超过2层的视图。
***************************************************************************************************************
    注意事项    :       此脚本来自下面参考资料。
***************************************************************************************************************
    脚本参数    :       无参数
***************************************************************************************************************
    参考资料    :       https://www.sqlservice.se/how-to-query-metadata-to-discover-nested-views/
***************************************************************************************************************
    更新记录    :      2018-04-15                    
*-**************************************************************************************************************/
;WITH cRefobjects
AS (
    -- Anchor level a view which refers to another view
    SELECT DISTINCT sed.referencing_id
        ,sed.referenced_id
        ,schema_name(o.schema_id) AS SchemaName
        ,o.name AS ViewName
        ,CONVERT(NVARCHAR(2000), N'>>' + schema_name(o.schema_id) + '.' + o.name) COLLATE DATABASE_DEFAULT AS NestViewPath
        ,o.type_desc
        ,1 AS LEVEL
    FROM sys.sql_expression_dependencies sed
    INNER JOIN sys.objects o ON o.object_id = sed.referencing_id
        AND o.type_desc = 'VIEW'
    LEFT OUTER JOIN sys.objects o2 ON o2.object_id = sed.referenced_id
        AND o2.type_desc IN ('VIEW')
    WHERE o2.object_id IS NULL

    UNION ALL

    -- Recursive part, retrieve any higher level views, build the path and increment the level
    SELECT sed.referencing_id
        ,sed.referenced_id
        ,s.name AS sch
        ,o.name AS viewname
        ,CONVERT(NVARCHAR(2000), cRefobjects.NestViewPath + N'>' + s.name + '.' + o.name) COLLATE DATABASE_DEFAULT
        ,o.type_desc
        ,LEVEL + 1 AS LEVEL
    FROM sys.sql_expression_dependencies AS sed
    INNER JOIN sys.objects o ON o.object_id = sed.referencing_id
        AND o.type_desc = 'VIEW'
    INNER JOIN sys.schemas AS s ON s.schema_id = o.schema_id
    INNER JOIN cRefobjects ON sed.referenced_id = cRefobjects.referencing_id
    )
SELECT DISTINCT SchemaName + '.' + ViewName AS ViewName
    ,NestViewPath
    ,type_desc
    ,LEVEL
FROM cRefobjects
WHERE LEVEL > 1
ORDER BY LEVEL DESC
    ,viewname
OPTION (MAXRECURSION 32);

标签:referenced,name,object,视图,Server,SQL,id,desc
From: https://www.cnblogs.com/kerrycode/p/17242337.html

相关文章

  • Mysql基本语法
    Mysql数据库基本语法:Mysql完整语法体系......
  • SQL—分组过滤group by函数与having函数
    题目:查看每个学校的平均发帖数(avg_question_cnt)和平均回帖数(avg_answer_cnt),并取出平均发帖数小于5的学校和平均回帖数小于20的学校。(保留3位小数)大佬的分解:1、限定条件......
  • MySQL基础:函数
    MySQL基础:函数函数是指一段可以直接被另一段程序调用的程序或代码。字符串函数MySQL中内置了很多字符串函数,常用的几个如下:函数功能CONCAT(S1,S2,...Sn)字符......
  • MySQL随记
    1、orvsunion对于单列来说,用or是没有任何问题的,但是or涉及到多个列的时候,每次select只能选取一个index,如果选择了area,population就需要进行table-scan,即全部扫描一遍,但......
  • MySQL介绍
    MySQL数据库最初是由瑞典MySQLAB公司开发,2008年1月16号被Sun公司收购。2009年,SUN又被Oracle收购。MySQL是目前IT行业最流行的开放源代码的数据库管理系统,同时它也是一个支......
  • MySQL介绍
    MySQL数据库最初是由瑞典MySQLAB公司开发,2008年1月16号被Sun公司收购。2009年,SUN又被Oracle收购。MySQL是目前IT行业最流行的开放源代码的数据库管理系统,同时它也是一个支......
  • macOS系统mamp搭建php连接sqlServer扩展,php连接sqlserver数据库
    macOS系统mamp搭建php连接sqlServer扩展,php连接sqlserver数据库下载:github上提供已经打包的os拓展文件https://github.com/Microsoft/msphpsql/releases打开php......
  • MySQL介绍
    MySQL数据库最初是由瑞典MySQLAB公司开发,2008年1月16号被Sun公司收购。2009年,SUN又被Oracle收购。MySQL是目前IT行业最流行的开放源代码的数据库管理系统,同时它也是一个支......
  • 使用SQL语句实现最短路线问题
    今天学习了一种直接用sql语句实现查询最短路径的方法,为我们的系统开发提供了便利。Stringsql="WITHRECURSIVEtransfer(start_station,stop_station,stops,path)......
  • SQL:DML、DQL、DCL
    SQL:DML、DQL、DCLDML:DataManipulationLanguage(数据操作语言)DML用来对数据库中的数据记录进行增删改操作。DML-添加数据给指定字段添加数据(一条数据)INSERTI......