Share via


Find the Database Where User Defined Object Located and Where it is Being Referred


Introduction

This article is based on a recent forum post asking whether there is any way to list the databases where a particular user defined function is located and also user wanted to know where this function is being referred. In this article I'm trying to put together all the suggestions and code samples received through various replies to arrive at a solution. 


Performing the test

The first solution was to use an undocumented system stored procedure sp_MSforeachdb. 

 Caution
This article uses the undocumented system stored procedure sp_MSforeachdb. Undocumented means it is safe to use in production but any support related to this command cannot be claimed from Microsoft.It also means that any change can be made to this command without officially notifying end user so unexpected results might come if used on same environment after some time. Although their usage is safe, keep in mind to use it in test environments only to avoid any impact to production processes. Syntax for this undocumented procedure is EXEC sp_MSforeachdb @command  (Where @command is a variable-length string) . Refer this for more information.


      exec sp_MSforeachdb 'use ? if exists(SELECT * from sys.objects where type = ''fn'' and name = ''split'' ) begin; print ''?''; end;';

A limitation of this method is that it only lists the database names where it is located, but it doesn't list other objects referring this one. 

Alternative method was to use catalog view  sys.sql_expression_dependencies along with dynamic management function sys.dm_sql_referenced_entities as shown below.

DECLARE @ObjectName NVARCHAR(100)
SET @ObjectName = 'split' --Give your function
 
SELECT DISTINCT
 SourceSchema                  = OBJECT_SCHEMA_NAME(sed.referencing_id)
 ,SourceObject                 = OBJECT_NAME(sed.referencing_id)
 ,ReferencedDB                 = ISNULL(sre.referenced_database_name, DB_NAME())
 ,ReferencedSchema             = ISNULL(sre.referenced_schema_name,
OBJECT_SCHEMA_NAME(sed.referencing_id))
 ,ReferencedObject             = sre.referenced_entity_name
FROM sys.sql_expression_dependencies sed
CROSS APPLY sys.dm_sql_referenced_entities(OBJECT_SCHEMA_NAME(sed.referencing_id)
+ '.' + OBJECT_NAME(sed.referencing_id), 'OBJECT') sre
WHERE sed.referenced_entity_name = @ObjectName
AND sre.referenced_entity_name = @ObjectName

A limitation with this approach is that the sys.sql_expression_dependencies catalog view contains information in the current database. We need to scroll through each and every database to get the information. To scroll through either you need to run the above command against each database or you need to use a cursor.

To overcome above limitations, use above code in conjunction with MS_foreachdb as below.  



      DECLARE @ObjectName NVARCHAR(100)
      SET @ObjectName = N'split' --Give your function
      Declare @MyQuery NVARCHAR(MAX) = N'
                            USE [?]      
                            SELECT DISTINCT      
                                SourceSchema                  = OBJECT_SCHEMA_NAME(sed.referencing_id)      
                                ,SourceObject                 = OBJECT_NAME(sed.referencing_id)      
                                ,ReferencedDB                 = ISNULL(sre.referenced_database_name, DB_NAME())      
                                ,ReferencedSchema             = ISNULL(sre.referenced_schema_name,      
                                OBJECT_SCHEMA_NAME(sed.referencing_id))      
                                ,ReferencedObject             = sre.referenced_entity_name      
                            FROM sys.sql_expression_dependencies sed      
                            CROSS APPLY sys.dm_sql_referenced_entities(OBJECT_SCHEMA_NAME(sed.referencing_id) + '      '.'      ' + OBJECT_NAME(sed.referencing_id), '      'OBJECT'      ') sre      
                            WHERE sed.referenced_entity_name like '      '%' + @ObjectName + '%'' AND sre.referenced_entity_name like ''%' + @ObjectName + '%''        
                       '      ;      
      EXEC sp_MSforeachdb  @MyQuery

Below is the sample result set.

Please find the link to download the full code from the Gallery - Link

Conclusion

As demonstrated above, one can make use of sys.sql_expression_dependencies catalog view and sys.dm_sql_referenced_entities DMF in conjunction with undocumented system stored procedure sp_MSforeachdb to search any objects in any databases in a SQL Instance with all the objects referring to it.

References

Note

when column dependencies cannot be resolved,sys.dm_sql_referenced_entities will throw error 2020.
Refer this and this articles to troubleshoot the same.