{"id":2089,"date":"2015-09-24T00:00:00","date_gmt":"2015-09-24T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/dependencies-and-references-in-sql-server\/"},"modified":"2026-03-09T13:44:49","modified_gmt":"2026-03-09T13:44:49","slug":"dependencies-and-references-in-sql-server","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/dependencies-and-references-in-sql-server\/","title":{"rendered":"SQL Server Dependencies: Find &#038; Track Object References"},"content":{"rendered":"\n<div id=\"pretty\">\n<p>SQL Server objects &#8211; tables, views, procedures, functions, triggers, types, and constraints &#8211; form a network of dependencies. Before you can safely rename, alter, or drop any object, you need to know what depends on it and what it depends on. SQL Server provides three approaches: the SSMS Object Explorer dependency viewer (visual, convenient), dynamic management views (sys.sql_expression_dependencies, sys.dm_sql_referencing_entities, sys.dm_sql_referenced_entities) for scripted queries, and PowerShell via SMO for automation. Dependencies are classified as soft (schema-bound &#8211; SQL Server prevents breaking changes) or hard (unvalidated references that may break silently). This article demonstrates all three approaches with AdventureWorks examples.<\/p>\n<h2>Introduction<\/h2>\n<p class=\"start\">In a relational database, it isn&#8217;t just the data that is related, but the database objects themselves. A view, for example, that references tables is dependent upon them, and wherever that view is used the function, procedure or view that uses it depends on it. Those tables referred to by the view may in turn contain user-defined types, or could be referenced to other tables via constraints. By its very nature, any SQL Server database will contain a network of inter-dependencies.<\/p>\n<p>SQL Server objects, such as tables, routines and views, often depend on other objects, either \u00a0because they refer to them in SQL Expressions, have constraints that access them, or use them. \u00a0There may be other objects that are, in turn, dependent on them. Dependencies grow like nets. It isn&#8217;t just foreign keys or SQL references that cause dependencies, but a whole range of objects such as triggers, user-defined types and rules. \u00a0It can complicate any changes to a database by requiring a specific order of operations within a database build script, or migration script. If you get it wrong, you&#8217;ll get a whole range of errors like &#8220;Cannot drop xxx &#8216;MyName&#8217; because it is being referenced by object &#8216;HisName&#8217; There may be other objects that reference this yyy&#8221;. or &#8221; xxx &#8216;MyName&#8217; references invalid xxx &#8216;HerName&#8217;.&#8221; Basically, objects need to be deleted or altered in a particular order. In a well-designed SQL Server database, or set of linked databases, it is easy to determine these dependencies, and work out the right sequence for doing things.<\/p>\n<h2>Finding dependencies via SSMS<\/h2>\n<p>Most of us need to think very little about finding out about dependencies, since SMO allows SSMS to get dependency information for us for any list of database objects, and display it in a tree structure. If you wish to know what dependencies an object has, or what it in turn depends on, You just right-click the object in the object explorer pane and click on &#8216;view dependencies&#8217; in the context menu that then appears.\u00a0<\/p>\n<figure><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-68455\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2015\/09\/2284-clip_image001.png\" alt=\"2284-clip_image001\" width=\"265\" height=\"330\" \/><\/figure>\n<p>\u00a0<\/p>\n<p>Your re-engineering work must take these dependencies into account. If you need to, for example, delete a column, your work must start at the &#8216;leaves&#8217; to make sure that nothing untoward references that column. If you change a user-defined table type, then you need to check wherever it has been used in the database. SSMS uses SMO to get this information. You can get the same information yourself, if you need to, by using a PowerShell script to get the same information from SMO. Accessing, in this example, the same table from the same database &#8230;<\/p>\n<pre class=\"theme:vs2012 font:consolas font-size:14 line-height:16 lang:ps decode:true \">Import-Module sqlserver -DisableNameChecking\n#load the SQLPS functionality for getting the registered servers\n\n#-- just to save typing ----\n$MS = 'Microsoft.SQLServer'\n$My = \"$MS.Management.Smo\"\n$Mc = \"$MS.Management.Common\"\n\n$dbname = \"Adventureworks2016\" #the database we want\n$tableName = 'Employee' #the table to investigate\n$schemaname = 'HumanResources' #the schema that the table is in\n$serverName = \"Philf01\" #the name of the server\n$credentials = 'user=Philfactor;pwd=ismellofpoo4U'\n# if SQL Server credentials, use 'user id=\"MyID;password=MyPassword\"'\n$DoWeLookForParentObjects = $false\n#look for the parent objects for each object-set to false for child objects\n\n#create the connection string\n$connectionString = `\n\"Data Source=$serverName;$credentials;pooling=False;multipleactiveresultsets=False;\"\n#connect to the server\ntry\n{\n  $sqlConnection = `\n    new-object System.Data.SqlClient.SqlConnection $connectionString\n  $conn = new-object \"$Mc.ServerConnection\" $sqlConnection\n  $srv = new-object Microsoft.SqlServer.Management.Smo.Server $conn\n}\ncatch\n{\n  \"Could not connect to SQL Server instance '$_.servername': $($error[0].ToString() +\n    $error[0].InvocationInfo.PositionMessage). Script is aborted\"\n  exit -1\n}\n#now get the SMO object for the table that we want.\n$success = $false\nif ($srv.Databases[$dbname] -ne $null)\n{\n  $db = $srv.Databases[$dbname]\n  if ($db.Tables.Contains($tableName, $schemaName))\n  { $table = new-object \"$My.Table\" ($db, $tableName, $schemaName);\n     $success = $true;}\n}\nif (-not $success)\n{\n  Write-error \"Couldn't find the $TableName table in the $dbname database\"\n  exit -1\n}\n#now  we set up the scripter object\n$scr = New-Object \"$My.Scripter\"\n#now choose options for the scripter that we need to get dependency order\n$options = New-Object \"$My.ScriptingOptions\"\n$options.DriAll = $True\n$options.AllowSystemObjects = $false\n$options.WithDependencies = $True\n$scr.Options = $options\n$scr.Server = $srv\n\n$VerbosePreference = \"Continue\"\n#we set up a URNcollection to contain our objects for analysis\n# (only one in this example)\n$urnCollection = new-object \"$my.UrnCollection\"\n$urnCollection.Add([Microsoft.SqlServer.Management.Sdk.Sfc.Urn]$table.Urn)\n#now we set up an event listnenr go get progress reports\n$ProgressReportEventHandler = [Microsoft.SqlServer.Management.Smo.ProgressReportEventHandler]  `\n   { Write-Verbose \"analysed '$($_.Current.GetAttribute('Name'))'\" }\n$scr.add_DiscoveryProgress($ProgressReportEventHandler)\n#create the dependency tree\n$dependencyTree =  `\n   $scr.DiscoverDependencies($urnCollection, $DoWeLookForParentObjects) \n#look for the parent objects for each object\n#and walk the dependencies to get the dependency tree.\n$depCollection = $scr.WalkDependencies($dependencyTree);\n#now we just show the dependency tree!\n$depCollection | %{\n  \"$(if ($_.IsRootNode -eq $true) { 'root: ' }\n     ) $($_.Urn.GetAttribute('Schema', $_.Urn.Type)\n     ).$($_.Urn.GetAttribute('Name', $_.Urn.Type)\n     )--$($_.Urn.Type)\"\n}\n\n$VerbosePreference = \"SilentlyContinue\"<\/pre>\n<p>Is there another way of doing this, hopefully in SQL? Well, yes there is, but I&#8217;ll be showing how to do that at the end of the article, and <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2284-ItDepends.html\"> providing the code<\/a>. But firstly, I&#8217;ll need to explain where some of the complications are.<\/p>\n<h2>Soft and hard Dependencies<\/h2>\n<p>Dependencies are of two types. \u00a0There are &#8216;soft&#8217; dependencies; references to other objects in SQL code that are exposed by sys.sql_expression_dependencies, and &#8216;hard&#8217; dependencies that are exposed by the object catalog views. &#8216;Hard&#8217; dependencies are inherent in the structure of the database, whereas code can reference objects in another database on the same server or on another server.<\/p>\n<h3>Soft Dependencies<\/h3>\n<div class=\"indent\">\n<p>\u00a0These soft dependencies are all recorded and are available from the <code>sys.sql_expression_dependencies<\/code>. If someone has allowed ad-hoc SQL to be generated by applications rather than use stored procedures or functions, you are free to weep at this point, because you have missed out on getting all this essential information and will find it very hard to refactor your database.<\/p>\n<p>&#8216;Soft&#8217; Dependencies happen when you have a routine (that is a procedure, function rule, constraint or anything else with code in it) that refers to another entity, possibly in another database. By dint of a SQL Expression in, say, a View, you can make that view dependent on one or more other objects. This dependency information is maintained by the database, but not for rules, defaults, temporary tables, temporary stored procedures, or system objects, and only when the referenced entity appears by name in a persisted SQL expression of the referencing entity.<\/p>\n<p>There are two types of soft dependency<\/p>\n<ul>\n<li><b>Schema-bound dependency<\/b><br \/>This is a relationship between two entities that means that there is an error if there is an attempt to drop the referenced entity when\u00a0 the referencing entity exists. This happens when a view or user-defined function uses the <code>WITH SCHEMABINDING<\/code> clause, or when a table has a <code>CHECK<\/code> or<code> DEFAULT <\/code>constraint or a computed column that references a user-defined function, user-defined type, or XML schema collection. If you execute an <strong>ALTER TABLE<\/strong> statement on a table that are referenced by views or UDFs that have schema binding, then you will get an error if the statement affects the view definition. The <code>WITH SCHEMABINDING<\/code> clause binds the view or UDF to the schema of the underlying base tables that they reference so that they cannot be modified in a way that would affect the view definition. The view or UDF must be dropped first.\u00a0 .<\/li>\n<li><b>Non-schema-bound dependency<\/b><br \/>This is a dependency relationship between two entities that does not trigger an error when the referenced entity is dropped or modified.<\/li>\n<\/ul>\n<p>Here is a simple query to find out in AdventureWorks, all the references that <code>Sales.vIndividualCustomer<\/code> makes<b><\/b><\/p>\n<pre class=\"theme:ssms2012 font:consolas font-size:14 line-height:16 lang:tsql decode:true \">SELECT Coalesce(Object_Schema_Name(referencing_id) + '.', '')\n       + --likely schema name\n  Object_Name(referencing_id) + --definite entity name\n  Coalesce('.' + Col_Name(referencing_id, referencing_minor_id), '') AS referencing,\n  Coalesce(referenced_server_name + '.', '')\n  + --possible server name if cross-server\n  Coalesce(referenced_database_name + '.', '')\n  + --possible database name if cross-database\n  Coalesce(referenced_schema_name + '.', '')\n  + --likely schema name\n  Coalesce(referenced_entity_name, '')\n  + --very likely entity name\n  Coalesce('.' + Col_Name(referenced_id, referenced_minor_id), '') AS referenced\n  FROM sys.sql_expression_dependencies\n  WHERE referencing_id = Object_Id('Sales.vIndividualCustomer')\n  ORDER BY referenced;<\/pre>\n<p>And here is a query that finds out all the objects that reference <b> &#8216;Sales.SalesOrderHeader&#8217;<\/b><\/p>\n<pre class=\"theme:ssms2012 font:consolas font-size:14 line-height:16 lang:tsql decode:true\">SELECT Coalesce(referenced_server_name + '.', '')\n       + --possible server name if cross-server\n  Coalesce(referenced_database_name + '.', '')\n       + --possible database name if cross-database\n  Coalesce(referenced_schema_name + '.', '') + --likely schema name\n  Coalesce(referenced_entity_name, '') + --very likely entity name\n  Coalesce('.' + Col_Name(referenced_id, referenced_minor_id), '') AS referencing,\n  Coalesce(Object_Schema_Name(referencing_id) + '.', '') + --likely schema name\n  Object_Name(referencing_id)\n  + --definite entity name\n  Coalesce('.' + Col_Name(referencing_id, referencing_minor_id), '') AS referenced\n  FROM sys.sql_expression_dependencies\n  WHERE referenced_id = Object_Id('Sales.SalesOrderHeader')\n  ORDER BY referenced;\n<\/pre>\n<p><code>Sys.sql_expression_dependencies<\/code> also has the information as to whether the dependency is schema-bound or not.<\/p>\n<p>Here is a routine that shows you the soft dependency order of the objects in your database, and lists the external dependencies of any objects. (note that a lot of entities in a database aren&#8217;t classed as objects. )<\/p>\n<\/div>\n<pre class=\"theme:ssms2012 font:consolas font-size:14 line-height:16 lang:tsql decode:true\">CREATE FUNCTION dbo.DependencyOrder ()\n\/* \nsummary:   &gt;\n This table-valued function is designed to give you the order in which\n database objects should be created in order for a build to succeed\n without errors. It uses the sys.sql_expression_dependencies table\n for the information on this.\n it actually only gives the level 1,,n so within the level the order\n is irrelevant so could, i suppose be done in parallel!\n It works by putting in successive passes, on each pass adding in objects\n who, if they refer to objects, only refer to those already in the table\n or whose parent object is already in the table. It goes on until no more\n objects can be added or it has run out of breath. If it does more than\n ten iterations it gives up because there must be a circular reference \n (I think that's impossible)\n \nRevisions:\n - Author: Phil Factor\n   Version: 1.0\n   Modification: First cut\n   date: 3rd Sept 2015\n example:\n     - code: Select * from dbo.DependencyOrder() order by theorder desc\nreturns:   &gt;\na table, giving the order in which database objects must be built\n \n*\/\nRETURNS @DependencyOrder TABLE\n  (\n  TheSchema VARCHAR(120) NULL,\n  TheName VARCHAR(120) NOT NULL,\n  Object_id INT PRIMARY KEY,\n  TheOrder INT NOT NULL,\n  iterations INT NULL,\n  ExternalDependency VARCHAR(2000) NULL\n  )\nAS\n  -- body of the function\n  BEGIN\n    DECLARE @ii INT, @EndlessLoop INT, @Rowcount INT;\n    SELECT @ii = 1, @EndlessLoop = 10, @Rowcount = 1;\n    WHILE @Rowcount &gt; 0 AND @EndlessLoop &gt; 0\n      BEGIN\n        ;WITH candidates (object_ID, Parent_object_id)\n         AS (SELECT sys.objects.object_id, sys.objects.parent_object_id\n               FROM sys.objects\n                 LEFT OUTER JOIN @DependencyOrder AS Dep \n                 --not in the dependency table already\n                   ON Dep.Object_id = objects.object_id\n               WHERE Dep.Object_id IS NULL AND type NOT IN ('s', 'sq', 'it'))\n        INSERT INTO @DependencyOrder (TheSchema, TheName, Object_id, TheOrder)\n        SELECT Object_Schema_Name(c.object_ID), Object_Name(c.object_ID),\n          c.object_ID, @ii\n          FROM candidates AS c\n            INNER JOIN @DependencyOrder AS parent\n              ON c.Parent_object_id = parent.Object_id\n        UNION\n        SELECT Object_Schema_Name(object_ID), Object_Name(object_ID),\n          object_ID, @ii\n          FROM candidates AS c\n          WHERE Parent_object_id = 0\n            AND object_ID NOT IN\n                  (\n                  SELECT c.object_ID\n                    FROM candidates AS c\n                      INNER JOIN sys.sql_expression_dependencies\n                        ON Object_id = referencing_id\n                      LEFT OUTER JOIN @DependencyOrder AS ReferedTo\n                        ON ReferedTo.Object_id = referenced_id\n                    WHERE ReferedTo.Object_id IS NULL\n                      AND referenced_id IS NOT NULL \n                      --not a cross-database dependency\n                  );\n        SET @Rowcount = @@RowCount;\n        SELECT @ii = @ii + 1, @EndlessLoop = @EndlessLoop - 1;\n      END;\n    UPDATE @DependencyOrder SET iterations = @ii - 1;\n    UPDATE @DependencyOrder\n      SET ExternalDependency = ListOfDependencies\n      FROM\n        (\n        SELECT Object_id,\n          Stuff(\n                 (\n                 SELECT ', ' + Coalesce(referenced_server_name + '.', '')\n                        + Coalesce(referenced_database_name + '.', '')\n                        + Coalesce(referenced_schema_name + '.', '')\n                        + referenced_entity_name\n                   FROM sys.sql_expression_dependencies AS sed\n                   WHERE sed.referencing_id = externalRefs.object_ID\n                     AND referenced_database_name IS NOT NULL\n                     AND is_ambiguous = 0\n                 FOR XML PATH(''), ROOT('i'), TYPE\n                 ).value('\/i[1]', 'varchar(max)'),1,2,'' ) \n                     AS ListOfDependencies\n          FROM @DependencyOrder AS externalRefs\n        ) AS f\n        INNER JOIN @DependencyOrder AS d\n          ON f.Object_id = d.Object_id;\n\n    RETURN;\n  END;\nGO<\/pre>\n<div class=\"indent\">\n<p>there are also two functions that provide information on soft dependencies<\/p>\n<ul>\n<li>The <code>sys.dm_sql_referenced_entities <\/code>Dynamic Management Function (DMF) returns every user-defined entity that is referenced by name in the definition of the referencing database object that you specify.<\/li>\n<li>The <code>sys.dm_sql_referencing_entities<\/code> DMF returns every user-defined entity in the current database that references the user-defined object, type (alias or CLR UDT), XML schema collection, or partition function that you specify.<\/li>\n<\/ul>\n<\/div>\n<h3>Hard Dependencies<\/h3>\n<div class=\"indent\">\n<p>&#8216;Hard&#8217; dependencies can happen whenever an object can reference another one. The rules are complicated.<\/p>\n<p>SQL Server\u00a0 has a number of types of objects and a whole lot of other entities that aren&#8217;t classed as database objects. The rules of what can reference what is best expressed as a table<\/p>\n<figure><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2284-Dependencies.png\" alt=\"2284-Dependencies.png\" width=\"542\" height=\"409\" \/><\/figure>\n<p>\u00a0<\/p>\n<\/div>\n<h1>Dependencies and Build Scripts.<\/h1>\n<p>Databases, in general, have to be built in the right order.\u00a0 This order avoids building anything that relies on an object that hasn&#8217;t been built yet. An easy way of doing this is to create objects in a particular order of object types.\u00a0 The downside of doing this is that objects that should really go together for clarity when inspecting scripts, such as tables, constraints, extended properties and indexes, get scattered in to different places for the convenience of an easy compilation. Clarity is sacrificed for convenience: also you will still need to do certain routines in soft dependency order.<\/p>\n<p>An exception to this is the CREATE SCHEMA statement that allows its contents to be created by CREATE SCHEMA\u00a0 in any order within the subsequent list, except for views that reference other views. In that case, the referenced view must be created before the view that references it. It is actually possible to use the CREATE SCHEMA statement without the schema name, but still allow the build list to be specified in any order other than views that reference views. However, this special syntax is deprecated.<\/p>\n<p>SMO likes to do build scripts in ObjectType order in a build script. The script starts with Database properties, followed by Schemas, XML Schema Collections and Types: none of which can have dependent objects. Table Types and Procedures come next. Then, in dependency order, Functions, Tables and Views. Then come Clustered indexes, non-clustered indexes, Primary XML Indexes, XML indexes, Default Constraints, Foreign keys Check constraints, triggers and lastly, extended properties. This order minimises the shuffling that needs to be done.\u00a0 Stored procedures are unique amongst modules or routines in that they have deferred compilation, which neatly kicks soft dependencies into touch for builds.<\/p>\n<h1>Cross-server, cross-database and cross-schema dependencies<\/h1>\n<h2>Cross-database dependencies<\/h2>\n<p>&#8216;Soft&#8217; dependencies are likely to refer to objects in other databases. These can be on the same server or on a different server. These can both be obtained from sys.sql_expression_dependencies.\u00a0 Sometimes, these can cause difficulties in the delivery process because they aren&#8217;t properly encapsulated in an interface of some sort, and aren&#8217;t wired into the build process. Often, these external references need to be &#8216;mocked&#8217; in development and only assigned to their destination during test or staging.\u00a0 This means that the actual routine that makes the external reference must \u00a0be related to the particular delivery environment (e.g. Integration Test, UAT, Performance Testing, staging and production), and the development build will have the source of the &#8216;mock&#8217; only. Each delivery environment is assigned the correct version of the code.\u00a0 The sys.sql_expression_dependencies is your friend in ensuring that all these external dependencies are tracked, and that none slip through the net to cause build problems. A warning though: XML documents are considered by SQL Server to be external databases and produce false positives when attempting to identify cross-database dependencies.<\/p>\n<h2>Cross-schema dependencies<\/h2>\n<p>I have worked with database developers who maintain hand-cut database build scripts that are done in a way that preserve dependency order whilst aiming at clarity. It is a pleasure to inspect, when done by one of the more professional developers, since it is generally well-documented. These are generally done, and saved in source-control, at schema level to allow more than one developer to work on the database concurrently. Cross-schema references are relevant here because the best practice is to reduce these to a minimum to allow as much autonomy as possible to the individual developer, avoid merges, and have as few build-breakages as possible. Here, with cross-schema references, both soft and hard dependencies are possible. Schema builds, unlike database builds, can list their object creation scripts in almost any order after the CREATE SCHEMA without errors.<\/p>\n<h1>Walking particular dependency types.<\/h1>\n<p>The reality of many dependency-based operations is that only one type of dependency is relevant, and not even the individual dependency chains. It just depends on &#8216;layers&#8217;. Take tables, for example. If you had a list in which the tables of a database were layered according to the fact that all their dependencies were satisfied by the preceding layer or below, then, as long as you do the operation to all of the layer below before the current one, then you aren&#8217;t going to break a dependency. I use this type of routine to to do fast-BCP loads into tables as part of a build, but it is also useful to establish an order of \u00a0build if your individual table scripts contain embedded foreign key definitions as either column or table constraint definitions.<\/p>\n<pre class=\"theme:ssms2012 font:consolas font-size:14 line-height:16 lang:tsql decode:true \">SET ANSI_NULLS ON\nGO\nSET QUOTED_IDENTIFIER ON\nGO\nIF OBJECT_ID (N'TempDB..#TablesInDependencyOrder') IS NOT NULL\n  DROP PROCEDURE #TablesInDependencyOrder\nGO\n \nCreate PROCEDURE #TablesInDependencyOrder\n\/**\nsummary:  \n  For the table(s) you specify, this routine returns a table containing all the related tables \n  in the current database, their schema, object_ID, and their\n  dependency level. \n  You would use this for deleting the data from tables or BCPing in the data.\n \nAuthor: Phil Factor\nRevision: 1.0 First cut\nCreated: 25th september 2015\nexample:\n    - \n      Declare @tables Table( TheObject_ID INT NOT null,\n      TheName SYSNAME NOT null,TheSchema SYSNAME NOT null,\n      HasIdentityColumn INT NOT null,TheOrder INT NOT null)\n      insert into @tables  \n         Execute #TablesInDependencyOrder\n      Select * from @Tables\n \n \nreturns: \n        TheObject_ID INT,--the tables' object ID\n        TheName SYSNAME, --the name of the table\n        TheSchema SYSNAME, --the schema where it lives\n        TheOrder INT) --Order by this column\n**\/\n \nAS\nSET NOCOUNT ON;\nDECLARE @Rowcount INT, @ii INT\nCREATE TABLE #tables (\n  TheObject_ID INT,--the tables' object ID\n  TheName SYSNAME, --the name of the table\n  TheSchema SYSNAME, --the schema where it lives\n  TheOrder INT DEFAULT 0) --we update this later to impose an order\n \n\/* We'll use a SQL 'set-based'  form of the topological sort. Firstly\nwe will read in all the desired tables identifying\nthe start nodes as level 1 These \"start nodes\" have no incoming edges\nat least one such node must exist in an acyclic graph*\/\n \nINSERT  INTO #tables (Theobject_ID, TheName, TheSchema, TheOrder)\n  SELECT  DISTINCT \n      TheTable.OBJECT_ID, TheTable.NAME, \n      object_schema_name(TheTable.OBJECT_ID) AS [Schema],\n      CASE WHEN --referenced.parent_object_ID IS NULL AND\n               referencing.parent_object_ID IS NULL THEN 1 ELSE 0 END AS TheOrder\n    FROM  sys.tables TheTable\n    -- LEFT OUTER JOIN sys.foreign_Keys referenced\n    -- ON referenced.referenced_Object_ID = TheTable.object_ID\n    LEFT OUTER JOIN sys.foreign_Keys referencing\n     ON referencing.parent_Object_ID = TheTable.object_ID\nSElECT @Rowcount=100,@ii=2\n--and then do tables successively as they become 'safe'\n \nWHILE @Rowcount &gt; 0\n  BEGIN\n  UPDATE  #tables\n  SET   TheOrder = @ii\n  WHERE   #tables.TheObject_ID IN (\n      SELECT  parent.TheObject_ID\n      FROM  #tables parent\n          INNER JOIN sys.foreign_Keys\n             ON sys.foreign_Keys.parent_Object_ID = parent.Theobject_ID\n          INNER JOIN #tables referenced\n             ON sys.foreign_Keys.referenced_Object_ID = referenced.Theobject_ID\n            AND sys.foreign_Keys.referenced_Object_ID &lt;&gt; parent.Theobject_ID\n      WHERE   parent.TheOrder = 0--i.e. it hasn't been ordered yet\n      GROUP BY parent.TheObject_ID\n      HAVING  SUM(CASE WHEN referenced.TheOrder = 0 THEN -20000\n               ELSE referenced.TheOrder\n            END) &gt; 0--where all its referenced tables have been ordered\n  )\n  SET @Rowcount = @@Rowcount\n  SET @ii = @ii + 1\n  IF @ii &gt; 100\n    BREAK\nEND\nSELECT TheObject_ID,TheName,TheSchema,TheOrder\n FROM #tables order by TheOrder\nIF @ii &gt; 100 --not a directed acyclic graph (DAG).\n  RAISERROR ('Cannot load in tables with mutual references in foreign keys',16,1)\nIF EXISTS ( SELECT  * FROM #tables WHERE TheOrder = 0 )\n  RAISERROR ('could not do the topological sort',16,1)\n \nGO\n<\/pre>\n<p>This sort of technique only works with some operations. With others, you need to follow a dependency branch from a particular object to track all the objects that a particular object depends on, and what depends on the object. This requires a more surgical approach based on the dependency tracker in SSMS. For a broader perspective that allows you to inspect an entire database, as well as to zoom in on detail, then SQL Dependency Tracker is ideal.<\/p>\n<p><strong>Read also:<br \/><\/strong><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/40-problems-sql-server-stored-procedure\/\" target=\"_blank\" rel=\"noopener\">Stored procedure problems and schema qualification<\/a><br \/><a href=\"https:\/\/www.red-gate.com\/simple-talk\/blogs\/sql-naming-conventions\/\" target=\"_blank\" rel=\"noopener\">SQL naming conventions<\/a><\/p>\n<h1>It_Depends<\/h1>\n<p>So is there another way to just simply list the dependencies, in other words the entities that depend on an object, and the ones that the object depends on, other than using PowerShell or the dependency displayer within SSMS? I use my own <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2284-ItDepends.html\">SQL-Based\u00a0 home-brewed dependency tracker<\/a> for the work I need it for. It is in SQL but its code is a bit long to list here in the article. <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2284-ItDepends.html\">It can be viewed here<\/a>. It shows a lot of what I&#8217;ve described in this article and in more detail. It gives you a similar display to the one in SSMS, but you can use it for other purposes as well, and it is rather faster! You can download it from the head of the article.<\/p>\n<p>You use it like this &#8230;<\/p>\n<pre class=\"theme:ssms2012 font:consolas font-size:14 line-height:16 lang:tsql decode:true\">\tUse AdventureWorks\n\tSELECT  space(iteration * 4) + TheFullEntityName + ' (' + rtrim(TheType) + ')'\n\tFROM    dbo.It_Depends('Employee',0)\n\tORDER BY ThePath\n<\/pre>\n<p>&#8230;to give a hierarchy like this.<\/p>\n<pre class=\"font:consolas font-size:14 line-height:16 lang:tsql decode:true\">\t    HumanResources.Employee (U)\n\t        dbo.ufnGetContactInformation (U)\n\t        dbo.uspGetEmployeeManagers (U)\n\t        dbo.uspGetManagerEmployees (U)\n\t        HumanResources.dEmployee (U)\n\t        HumanResources.EmployeeAddress (U)\n\t        HumanResources.EmployeeDepartmentHistory (U)\n\t        HumanResources.EmployeePayHistory (U)\n\t        HumanResources.JobCandidate (U)\n\t            HumanResources.vJobCandidate (U)\n\t            HumanResources.vJobCandidateEducation (U)\n\t            HumanResources.vJobCandidateEmployment (U)\n\t        HumanResources.uspUpdateEmployeeHireInfo (U)\n\t        HumanResources.uspUpdateEmployeeLogin (U)\n\t        HumanResources.uspUpdateEmployeePersonalInfo (U)\n\t        HumanResources.vEmployee (U)\n\t        HumanResources.vEmployeeDepartment (U)\n\t        HumanResources.vEmployeeDepartmentHistory (U)\n\t        Purchasing.PurchaseOrderHeader (U)\n\t            Purchasing.iPurchaseOrderDetail (U)\n\t            Purchasing.PurchaseOrderDetail (U)\n\t            Purchasing.uPurchaseOrderDetail (U)\n\t            Purchasing.uPurchaseOrderHeader (U)\n\t        Sales.SalesPerson (U)\n\t            Sales.SalesOrderHeader (U)\n\t                Sales.CalculateSalesOrderTotal (U)\n\t                Sales.iduSalesOrderDetail (U)\n\t                Sales.SalesOrderDetail (U)\n\t                    Sales.OrderWeight (U)\n\t                Sales.SalesOrderHeaderAudit (U)\n\t                Sales.SalesOrderHeaderSalesReason (U)\n\t            Sales.SalesPersonQuotaHistory (U)\n\t            Sales.SalesTerritoryHistory (U)\n\t            Sales.Store (U)\n\t                Sales.iStore (U)\n\t                Sales.iuIndividual (U)\n\t                Sales.StoreContact (U)\n\t                Sales.vStoreWithDemographics (U)\n\t            Sales.uSalesOrderHeader (U)\n\t        Sales.vSalesPerson (U)\n\t        Sales.vSalesPersonSalesByFiscalYears (U)\n\t<\/pre>\n<p>It is a bit rugged when compared with what you can achieve via SSMS, but it is quicker, and great for SQL development work when you are having to check out a rats-nest of dependencies. (To use it with SQL Server 2008, you&#8217;ll need to nick out the statement that accesses <code>sys.sequences<\/code>, together with it&#8217;s accompanying <code>UNION ALL)<\/code><\/p>\n<h1>Conclusions<\/h1>\n<p>If you can be sure about the way that the database objects you&#8217;re working on depend on each other and upon other database objects, both in the database and outside it, then it becomes a lot easier and more restful to re-engineer a database. Refactoring becomes less like an extreme sport, and more like knitting. If your database sticks to the convention of using only compiled routines such as stored procedures and functions, then you will know what references that table you want to get rid of, or what needs to be reworked when you alter that user-defined table type.\u00a0 Any tool, or combination of tools, that track dependencies are going to be very useful to you.<\/p>\n<\/div>\n\n\n\n<section id=\"my-first-block-block_41ea1dff3b8e7b5283090c7824fda2c6\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">Fast, reliable and consistent SQL Server development&#8230;<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            &#8230;with SQL Toolbelt Essentials. 10 ingeniously simple tools for accelerating development, reducing risk, and standardizing workflows.                                    <\/div>\n            <\/div>\n                            <a href=\"https:\/\/www.red-gate.com\/products\/sql-toolbelt-essentials\/\" class=\"btn btn--secondary btn--lg\">Learn more &amp; try for free<\/a>\n                    <\/div>\n    <\/div>\n<\/section>\n\n\n<section id=\"faq\" class=\"faq-block my-5xl\">\n    <h2>FAQs: Dependencies and references in SQL Server<\/h2>\n\n                        <h3 class=\"mt-4xl\">1. How do you find object dependencies in SQL Server?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Three methods: (1) SSMS: right-click any object \u2192 View Dependencies for a visual tree. (2) DMVs: query sys.sql_expression_dependencies for compile-time references, sys.dm_sql_referencing_entities for \u201cwhat references this object,\u201d and sys.dm_sql_referenced_entities for \u201cwhat does this object reference.\u201d (3) PowerShell\/SMO: use the Scripter class with DependencyType to generate ordered scripts. The DMV approach is most flexible for custom queries across large databases.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">2. What is the difference between soft and hard dependencies in SQL Server?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Soft dependencies are schema-bound: SQL Server validates them at compile time and prevents breaking changes (you can\u2019t drop a table referenced by a schema-bound view). Hard dependencies are unvalidated references in dynamic SQL, EXEC statements, or cross-database queries &#8211; SQL Server doesn\u2019t track these, so they can break silently when objects are renamed or dropped.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">3. How do you script objects in dependency order?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Use PowerShell with the SMO Scripter class, setting DependencyType to TreeDependency. This generates scripts in the correct order for deployment. Alternatively, query sys.sql_expression_dependencies recursively using a CTE to build a topological sort of object creation order. The dependency chain determines which objects must be created first.<\/p>\n            <\/div>\n            <\/section>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Find and track object dependencies in SQL Server using SSMS, DMVs, and PowerShell. Covers soft vs hard dependencies, sys.sql_expression_dependencies, and referencing\/referenced entity views.&hellip;<\/p>\n","protected":false},"author":154613,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143531],"tags":[4168,4150,4151,4252],"coauthors":[6813],"class_list":["post-2089","post","type-post","status-publish","format-standard","hentry","category-t-sql-programming-sql-server","tag-database","tag-sql","tag-sql-server","tag-t-sql-programming"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/2089","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/154613"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=2089"}],"version-history":[{"count":20,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/2089\/revisions"}],"predecessor-version":[{"id":109064,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/2089\/revisions\/109064"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=2089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=2089"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=2089"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=2089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}