In SQL Server 2008, the
object names that a stored procedure references do not have to exist at
the time the procedure is created. SQL Server 2008 checks for the
existence of database objects at the time the stored procedure is
executed and returns an error message at runtime if the referenced
object doesn’t exist. The only exception is when a stored procedure
references another stored procedure that doesn’t exist. In that case, a
warning message is issued, but the stored procedure is still created
(see Listing 1).
Listing 1. Procedure Name Resolution During Stored Procedure Creation
create proc p2
as
exec p3
go
The module 'p2' depends on the missing object 'p3'. The module will still be
created; however, it cannot run successfully until the object exists.
|
When a table or view does
exist at procedure creation time, the column names in the referenced
table are validated. If a column name is mistyped or doesn’t exist, the
procedure is not created (see Listing 2).
Listing 2. Column Name Validation in Stored Procedures
IF EXISTS ( SELECT * FROM sys.procedures
WHERE schema_id = schema_id('dbo')
AND name = N'get_authors_and_titles')
DROP PROCEDURE dbo.get_authors_and_titles
GO
create proc get_authors_and_titles
as
select a.au_lname, au_fname, title, isbn_number
from authors a join titleauthor ta on a.au_id = ta.au_id
join titles t on t.title_id = ta.title_id
return
go
Server: Msg 207, Level 16, State 1, Procedure get_authors_and_titles, Line 4
Invalid column name 'isbn_number'.
|
One advantage of delayed (or deferred) name
resolution is the increased flexibility when creating stored procedures;
the order of creating procedures and the tables they reference does not
need to be exact. Delayed name resolution is an especially useful
feature when a stored procedure references a temporary table that isn’t
created within that stored procedure. However, at other times, it can be
frustrating to have a stored procedure create successfully only to have
it fail when it runs due to a missing table, as shown in Listing 3.
Listing 3. Runtime Failure of a Stored Procedure with an Invalid Object Reference
create proc get_authors_and_titles
as
select a.au_lname, au_fname, title, pub_date
from authors a join titleauthor ta on a.au_id = ta.au_id
join books t on t.title_id = ta.title_id
go
EXEC get_authors_and_titles
go
Server: Msg 208, Level 16, State 1, Procedure get_authors_and_titles, Line 4
Invalid object name 'books'.
|
Another
issue to be careful of with deferred name resolution is that you can’t
rename objects referenced by stored procedures and have the stored
procedure continue to work. In versions of SQL Server prior to 7.0,
after the stored procedure was created, object references within the
stored procedure were made via the object ID rather than the object
name. This allowed stored procedures to continue to function properly if
a referenced object was renamed. However, now that object names are
resolved at execution time, the procedure fails at the statement
referencing the renamed object. For the stored procedure to execute
successfully, it needs to be altered to specify the new object name.
Identifying Objects Referenced in Stored Procedures
Because changing the name of a table can cause stored
procedures to no longer work, you might want to identify which stored
procedures reference a specific table so you know which stored
procedures will be affected by changes to the table name or columns. You
can view the dependencies between database objects by querying the sys.sql_dependencies object catalog view. Unfortunately, all you really see if you query the sys.sql_dependencies
view is a bunch of numbers—just the IDs of the objects and columns that
have a dependency relationship, along with some additional status
information.
The better way to display a list of stored procedures
that reference a specific table or view, or to display a list of
objects referenced by a stored procedure, is to use the sys.dm_sql_referencing_entities and sys.dm_sql_referenced_entities dynamic management functions.
sys.dm_sql_referencing_entities ( ' schema_name.table_or_view_name ' , ' OBJECT ' )
sys.dm_sql_referenced_entities ( ' schema_name.proc_name ' , ' OBJECT ' )
For example, to display the stored procedures, triggers, functions, and views that reference the titles table, you would execute the following:
select referencing_schema_name, referencing_entity_name
From sys.dm_sql_referencing_entities ( 'dbo.titles' , 'OBJECT' )
go
In the bigpubs2008 database, the titles table is referenced by the following:
referencing_schema_name referencing_entity_name
-------------------------------------------------
dbo AverageBookPrice
dbo AverageBookPrice2
dbo AveragePricebyType
dbo AveragePricebyType2
dbo reptq1
dbo reptq2
dbo reptq3
dbo title_authors
dbo titleview
dbo valid_book_types
To display the objects referenced by the title_authors stored procedure, you could execute the following:
select distinct
referenced_entity_name as table_name,
referenced_minor_name as column_name
From sys.dm_sql_referenced_entities ('dbo.title_authors' , 'OBJECT' )
go
In the current database, the specified object references the following:
table_name column_name
----------------------------
authors NULL
authors au_fname
authors au_id
authors au_lname
titleauthor NULL
titleauthor au_id
titleauthor title_id
titles NULL
titles title
titles title_id
You can also see dependency information in SSMS by
right-clicking an object and choosing View Dependencies. This brings up
the Object Dependencies window, as shown in Figure 1.
You can view either the objects that depend on the selected object or
objects on which the selected object depends. You can also expand the
dependency tree for the objects listed in the Dependencies pane.