SQL, Analysis Services & related stories.

SQL 2000 to SQL 2005 migration: temporary tables reuse issue.

During the same project the next issue was found: temporary table reuse. Here is an example on “how to reproduce”:

USE tempdb

GO

 

CREATE PROCEDURE dbo.usp_step_one

AS

BEGIN

                CREATE TABLE #temp (ID INT NOT NULL, NUM INT)

                ALTER TABLE #temp ADD CONSTRAINT PK_ID PRIMARY KEY (ID)

                INSERT INTO #temp SELECT 1, 1

END

GO

 

CREATE PROCEDURE dbo.usp_step_two

AS

BEGIN

                CREATE TABLE #temp (ID INT NOT NULL, NUM INT)

                INSERT INTO #temp SELECT 1, 1

END

GO

 

BEGIN TRAN

EXEC dbo.usp_step_one

PRINT 'step one 1'

 

EXEC dbo.usp_step_one

PRINT 'step one 2'

 

EXEC dbo.usp_step_two

PRINT 'step two 1'

COMMIT

GO

 

DROP PROCEDURE dbo.usp_step_one

DROP PROCEDURE dbo.usp_step_two

GO

 

SQL 2000 will process this batch without errors, but SQL 2005 will get you the following results:

 

step one 1

Msg 2714, Level 16, State 4, Procedure usp_step_one, Line 6

There is already an object named 'PK_ID' in the database.

Msg 1750, Level 16, State 0, Procedure usp_step_one, Line 6

Could not create constraint. See previous errors.

 

The problem is in temporary tables caching during transaction. In SQL 2000 it always used to drop local temp tables as soon as they get out of scope. In SQL 2005, the drop is delayed until the transaction is gone (rollback / commit). You can find some more details about temp tables caching here. As a workaround you can:

-          Use table variables instead of temporary tables

-          Avoid named constraint creation on temporary objects like

 

CREATE TABLE #temp (ID INT NOT NULL PRIMARY KEY CLUSTERED, NUM INT)

 

Published Saturday, April 28, 2007 8:55 PM by Igor Kovalenko

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Kris said:

What are table variables? Can you elaborate on that.

Thanks.

April 28, 2007 9:33 PM
 

Igor Kovalenko said:

I meen you may try to use something like that

declare @temp TABLE  (ID INT NOT NULL PRIMARY KEY, NUM INT)

April 29, 2007 6:53 PM
 

Mike said:

We ran into the same thing in our production code. I was nasty to trace because they were nested stored procedures using the same #table name with differing schema (not my design).  The whole thing makes seems analogous to c# and garbage - delayed.

June 20, 2007 10:29 AM
 

Fitzer said:

Rather than use a primary key , consider using a clustered key and precede the name with  a #

               CREATE CLUSTERED INDEX [#temp_CIDX] ON #temp

(

[ID] ASC

)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]

You will not have the Primary key constraint feature but you will have the benefit from indexing and stats.

August 3, 2007 7:44 AM
 

Ryan said:

Great suggestion.  I had this same issue however unfortunately for me the additional challenge that my clustered PK key had to be on 2 columns, in which case you do have to name the constraint.  In order to avoid a naming conflict for that constraint my solution was to dynamically execute the DDL code to create the table, this way I created a unique constraint name on the fly.  You have to run dynamic sql, but sometimes that's just what works.  You'll end up with your PK constraint and no naming conflicts.

DECLARE @CreateString nvarchar(512)

SET @CreateString = N'CREATE TABLE ##temp

   ([ID_ONE] int NOT NULL, [ID_TWO] int NOT NULL, [NUM] int,

   CONSTRAINT [PK_ID_' + Cast(NEWID() as nvarchar(50)) + '] PRIMARY KEY CLUSTERED

       ([ID_ONE], [ID_TWO]) WITH (IGNORE_DUP_KEY = OFF)) ON [PRIMARY]'

exec sp_executesql @CreateString

December 14, 2007 10:28 AM

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required
Submit

About Igor Kovalenko

I've been in IT since 1991 starting my carrier on Unix & C development. Now i am a consultant in Microsoft Services, Russia. My areas of experience - SQL & OLAP. I've been working with Microsoft tools for more than 15 years, started from asm 5.0 and Quick C 2.51 through (Visual) FoxPro, VB, C#... But my mission is SQL. Truly says i have enough knowledge both Oracle (8, 9.i) and Microsoft db technology, but it's to hard for me to cover both :-). My real data warehousing experience started with one of the largest DW implementation with using Oracle 9i in Russia till 2002. Of course i also implemented the first part of BI project on top of this DW with using SQL AS 2000 & Crystal reports. After that for a year i was a seniour developer, Online Services, in Dell UK, Bracknell (c++/vb/Oracle/SQL/ASP). In 2003 i was a little bit tired from High Technology World and decided to join Deloitte, Moscow, where i was a Finance analyst, member of Business Director Group. I really miss a half of my IT knowledge this time (SQL & Crystal is only useful), but now i perfectly know the "underground" of any BIG 4 consulting company, budgeting and managing process details, FTE, Utilization, OPTS analysis.... Hell, real accounting hell. I was excited to design and implement my first (and last) project with using Cognos EP tool. At the end of 2005 i was hired by my favorite company :-) Microsoft and now i am working with my favorite tool: SQL Server. To keep a long story short :-).

© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker