Login or Sign Up to become a member!

EXPERTS, INFORMATION, IDEAS & KNOWLEDGE

Social bookmarker Add this

Your profile

Search

September 2008
Mon Tue Wed Thu Fri Sat Sun
 << <   > >>
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          

XML Feeds

The Data Management Journal

What is deferred name resolution and why do you need to care?

by SQLDenis


Permalink 08 Sep 2008 08:23 , Categories: Data Modelling & Design Tags: gotcha, howto, sql server, t-sql, tip, trick

So I posted a teaser in the puzzles forum. Without running this, try to guess what will happen?

  1. DECLARE @x INT
  2.  
  3. SET @x = 1
  4.  
  5. IF (@x = 0)
  6. BEGIN
  7.     SELECT 1 AS VALUE INTO #temptable
  8. END
  9. ELSE
  10. BEGIN
  11.    SELECT 2 AS VALUE INTO #temptable
  12. END
  13.  
  14. SELECT * FROM #temptable –what does this return

This is the error you get
Server: Msg 2714, Level 16, State 1, Line 12
There is already an object named ‘#temptable’ in the database.

You can do something like this to get around the issue with the temp table

  1. DECLARE @x INT
  2.  
  3. SET @x = 1
  4.  
  5. CREATE TABLE #temptable (VALUE INT)
  6. IF (@x = 0)
  7. BEGIN
  8.     INSERT #temptable
  9.     SELECT 1
  10. END
  11. ELSE
  12. BEGIN
  13.     INSERT #temptable
  14.     SELECT 2
  15. END
  16.  
  17. SELECT * FROM #temptable –what does this return

So what is thing called Deferred Name Resolution? Here is what is explained in Books On Line

When a stored procedure is created, the statements in the procedure are parsed for syntactical accuracy. If a syntactical error is encountered in the procedure definition, an error is returned and the stored procedure is not created. If the statements are syntactically correct, the text of the stored procedure is stored in the syscomments system table.

When a stored procedure is executed for the first time, the query processor reads the text of the stored procedure from the syscomments system table of the procedure and checks that the names of the objects used by the procedure are present. This process is called deferred name resolution because objects referenced by the stored procedure need not exist when the stored procedure is created, but only when it is executed.

In the resolution stage, Microsoft SQL Server 2000 also performs other validation activities (for example, checking the compatibility of a column data type with variables). If the objects referenced by the stored procedure are missing when the stored procedure is executed, the stored procedure stops executing when it gets to the statement that references the missing object. In this case, or if other errors are found in the resolution stage, an error is returned.

So what is happening is that beginning with SQL server 7 deferred name resolution was enabled for real tables but not for temporary tables. If you change the code to use a real table instead of a temporary table you won’t have any problem
Run this to see what I mean

  1. DECLARE @x INT
  2.  
  3. SET @x = 1
  4.  
  5. IF (@x = 0)
  6. BEGIN
  7.     SELECT 1 AS VALUE INTO temptable
  8. END
  9. ELSE
  10. BEGIN
  11.    SELECT 2 AS VALUE INTO temptable
  12. END
  13.  
  14. SELECT * FROM temptable –what does this return

What about variables? Let’s try it out, run this

  1. DECLARE @x INT
  2.  
  3. SET @x = 1
  4.  
  5. IF (@x = 0)
  6. BEGIN
  7.     DECLARE @i INT
  8.     SELECT @i = 5
  9. END
  10. ELSE
  11. BEGIN
  12.    DECLARE @i INT
  13.    SELECT @i = 6
  14. END
  15.  
  16. SELECT @i

And you get the follwing error
Server: Msg 134, Level 15, State 1, Line 13
The variable name ‘@i’ has already been declared. Variable names must be unique within a query batch or stored procedure.

Now why do you need to care about deferred name resolution? Let’s take another example from a blogpost I made a while back: Do you depend on sp_depends (no pun intended)

First create this proc

  1. CREATE PROC SomeTestProc
  2. AS
  3. SELECT dbo.somefuction(1)
  4. GO

now create this function

  1. CREATE FUNCTION somefuction(@id INT)
  2. RETURNS INT
  3. AS
  4. BEGIN
  5. SELECT @id = 1
  6. RETURN @id
  7. END
  8. Go

now run this

  1. SP_DEPENDS ’somefuction’

result: Object does not reference any object, and no objects reference it.

Most people will not create a proc before they have created the function. So when does this behavior rear its ugly head? When you script out all the objects in a database, if the function or any objects referenced by an object are created after the object that references them then sp_depends won’t be 100% correct

SQL Server 2005 makes it pretty easy to do it yourself

  1. SELECT specific_name,*
  2. FROM information_schema.routines
  3. WHERE object_definition(OBJECT_ID(specific_name)) LIKE ‘%somefuction%’
  4. AND routine_type = ‘procedure’
3 comments »Send a trackback » 50 views

Get A Free SQL Server 2008 Ebook

by SQLDenis


Permalink 04 Sep 2008 08:32 , Categories: Data Modelling & Design Tags: book, products, red gate, tools

Download a trial version of Red Gate’s SQL Toolbelt 2008 and get Brad’s Sure Guide to SQL Server 2008 for free

Products included in the SQL Toolbelt 2008:

SQL Compare Pro
SQL Data Compare Pro
SQL Packager Pro
SQL Prompt Pro
SQL Doc Pro
SQL Backup Pro
SQL Data Generator
SQL Dependency Tracker
SQL Refactor
SQL Multi Script
SQL Comparison SDK

I have been using Red Gate’s products since 2002 and must say that they have saved me tons of work/time many times.

Here is the link to the site: Brad’s Sure Guide to SQL Server 2008

1 comment »Send a trackback » 226 views

Find Out The Recovery Model For Your Database

by SQLDenis


Permalink 30 Aug 2008 08:18 , Categories: Data Modelling & Design Tags: administration, database, sql, sql server

You want to quickly find out what the recovery model is for your database but you don’t want to start clicking and right-clicking in SSMS/Enterprise Manager to get that information. This is what you can do, you can use databasepropertyex to get that info. Replace ‘msdb’ with your database name

  1. SELECT DATABASEPROPERTYEX(‘msdb’,‘Recovery’)

What if you want it for all databases in one shot? No problem here is how, this will work on SQL Server version 2000

  1. SELECT name,DATABASEPROPERTYEX(name,‘Recovery’)
  2.  FROM sysdatabases

For SQL Server 2005 and up, you should use the following command

  1. SELECT name,recovery_model_desc
  2. FROM sys.databases

I have also added this to our SQL Server admin Wiki here: Find Out The Recovery Model For Your Database
Make sure to check out the other wiki entries

If you have a SQL related question try our Microsoft SQL Server Programming forum or our Microsoft SQL Server Admin forum

Leave a comment »Send a trackback » 369 views

How to Rebuild System Databases in SQL Server 2008

by SQLDenis


Permalink 29 Aug 2008 12:45 , Categories: Data Modelling & Design Tags: administration, sql server 2008, system databases

The PSS SQL Server Engineers made a nice blogpost explaining How to Rebuild System Databases in SQL Server 2008

In SQL Server 2005, we introduced a different method than in previous versions to rebuild system databases (affectionately known as “rebuild master"). You were required to use the setup.exe program with command line switches.

This is no different in SQL Server 2008 but the command line switches have changed some and the process behind the scenes to rebuild the system databases (master, model, and msdb) is also a bit different.

The cool part about the way they are doing this is that you don’t need your DVD anymore!

You should bookmark that page immediately so that you can find it when you need and before you suffer that enormous panic attack :-)

2 comments »Send a trackback » 147 views

LINQ to SQL queries involving strings cause SQL Server procedure cache bloat

by SQLDenis


Permalink 28 Aug 2008 10:12 , Categories: Data Modelling & Design Tags: bug, linq, performance

Adam Machanic created an item on connect explaining how LINQ to SQL queries involving strings cause SQL Server procedure cache bloat

If an application is using LINQ to SQL and the queries involve the use of strings that can be highly variable in length, the SQL Server procedure cache will become bloated with one version of the query for every possible string length. For example, consider the following very simple queries created against the Person.AddressTypes table in the AdventureWorks2008 database:

  1. var p =
  2.                 from n in x.AddressTypes
  3.                 where n.Name == "Billing"
  4.                 select n;
  5.  
  6.             var p =
  7.                 from n in x.AddressTypes
  8.                 where n.Name == "Main Office"
  9.                 select n;

If both of these queries are run, we will see two entries in the SQL Server procedure cache: One bound with an NVARCHAR(7), and the other with an NVARCHAR(11). Now imagine if there were hundreds or thousands of different input strings, all with different lengths. The procedure cache would become unnecessarily filled with all sorts of different plans for the exact same query. Even worse, imagine if a query used two or three different string parameters. The procedure cache could end up with hundreds of thousands or even millions of entries, the only differences being the variable lengths

Wow that is bad indeed, please go to the connect site and vote for this so that Microsoft ‘fixes’ this. Here is the URL: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363290

4 comments »Send a trackback » 570 views

:: Next >>