views:

13

answers:

1

If I have two trivial stored procedures, created like so:

create procedure root as
select 1 
go

create procedure dependant as
exec root
go

(Where dependant depends on root).

When I check the sys.sql_dependencies table for the second procedure, I see an entry (as i would expect).

If, however, I add the dependant procedure first, I get the following warning.

Cannot add rows to sys.sql_dependencies for the stored procedure because it depends on the missing table 'root'. The stored procedure will still be created; however, it cannot be successfully executed until the table exists.

And, right enough, exec dependant; fails.

So, when I add in the root procedure, exec dependant; works, however, no dependency is recorded on sys.sql_dependencies.

My questions are twofold:

  1. What are the consequences of this?
  2. Everything seems to hang together quite acceptably, so why doesn't SQL add this record retrospectively?

Help, as always is much appreciated.

+1  A: 

The consequences are just that when you come to refactor the database it is more difficult to identify affected objects.

You can refresh all dependencies by writing a script to run sp_refreshsqlmodule on all database objects.

In SQL Server 2008 such unresolved dependencies are still stored and are accessible through sys.sql_expression_dependencies meaning the dependency information is more reliable.

The SQL Server 2008 behaviour is as follows.

After dependant is created but before root exists

SELECT     OBJECT_NAME(referencing_id) AS Name, 
           referencing_class_desc, 
           referenced_class_desc, 
           referenced_entity_name, 
           referenced_id, 
           is_caller_dependent, 
           is_ambiguous
FROM         sys.sql_expression_dependencies

Returns

Name       referenced_entity_name    referenced_id is_caller_dependent is_ambiguous
---------- ------------------------- ------------- ------------------- ------------
dependant  root                      NULL          1                   0

In your example code this is also the results of the query following the creation of root as the reference to it is not schema qualified and so is caller dependent. However if the definition of your dependant procedure is changed to

create procedure dependant as
exec dbo.root

Then once dbo.root is created the following is returned

Name       referenced_entity_name    referenced_id is_caller_dependent is_ambiguous
---------- ------------------------- ------------- ------------------- ------------
dependant  root                      2121058592    0                   0
Martin Smith