场景:在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_namevarchar(128)
set@object_name='dbo.v_SecPolicyInfo'

;WITHcte_objects
AS
(
SELECT1asnested_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
FROMsys.sql_expression_dependenciesd
WHEREd.referencing_id=object_id(@object_name)
UNIONALL
SELECTt.nested_level+1nested_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
FROMsys.sql_expression_dependenciesd
INNERJOINcte_objectst
ONt.referenced_id=d.referencing_id
)

SELECTd.nested_level
,schema_name(o.schema_id)+'.'+o.nameasobject_name
,o.type_desc
,ISNULL(d.referenced_server_name,@@SERVERNAME)asreferenced_server_name
,ISNULL(d.referenced_database_name,DB_NAME())asreferenced_database_name
,d.referenced_class_desc
,ISNULL(d.referenced_schema_name,'dbo')
+'.'+d.referenced_entity_nameasreferenced_entity_name
,p.type_descasreferenced_object_type

FROMcte_objectsd
INNERJOINsys.objectso
ONd.referencing_id=o.object_id
INNERJOINsys.objectsp
ONd.referenced_id=p.object_id;

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

/*-*************************************************************************************************************
--脚本名称:get_netsted_view_level.sql
--脚本作者:FredrikRundgren
--创建日期:2018-04-15
***************************************************************************************************************
脚本功能:找出数据库视图嵌套视图的视图/嵌套超过2层的视图。
***************************************************************************************************************
注意事项:此脚本来自下面参考资料。
***************************************************************************************************************
脚本参数:无参数
***************************************************************************************************************
参考资料:https://www.sqlservice.se/how-to-query-metadata-to-discover-nested-views/
***************************************************************************************************************
更新记录:2018-04-15
*-**************************************************************************************************************/

;WITHcRefobjects
AS(
--Anchorlevelaviewwhichreferstoanotherview
SELECTDISTINCTsed.referencing_id
,sed.referenced_id
,schema_name(o.schema_id)ASSchemaName
,o.nameASViewName
,CONVERT(NVARCHAR(2000),N'>>'+schema_name(o.schema_id)+'.'+o.name)COLLATEDATABASE_DEFAULTASNestViewPath
,o.type_desc
,1ASLEVEL
FROMsys.sql_expression_dependenciessed
INNERJOINsys.objectsoONo.object_id=sed.referencing_id
ANDo.type_desc='VIEW'
LEFTOUTERJOINsys.objectso2ONo2.object_id=sed.referenced_id
ANDo2.type_descIN('VIEW')
WHEREo2.object_idISNULL

UNIONALL

--Recursivepart,retrieveanyhigherlevelviews,buildthepathandincrementthelevel
SELECTsed.referencing_id
,sed.referenced_id
,s.nameASsch
,o.nameASviewname
,CONVERT(NVARCHAR(2000),cRefobjects.NestViewPath+N'>'+s.name+'.'+o.name)COLLATEDATABASE_DEFAULT
,o.type_desc
,LEVEL+1ASLEVEL
FROMsys.sql_expression_dependenciesASsed
INNERJOINsys.objectsoONo.object_id=sed.referencing_id
ANDo.type_desc='VIEW'
INNERJOINsys.schemasASsONs.schema_id=o.schema_id
INNERJOINcRefobjectsONsed.referenced_id=cRefobjects.referencing_id
)
SELECTDISTINCTSchemaName+'.'+ViewNameASViewName
,NestViewPath
,type_desc
,LEVEL
FROMcRefobjects
WHERELEVEL>1
ORDERBYLEVELDESC
,viewname
OPTION(MAXRECURSION32);

扫描上面二维码关注我如果你真心觉得文章写得不错,而且对你有所帮助,那就不妨帮忙“推荐”一下,您的“推荐”和”打赏“将是我最大的写作动力!本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.