8

I have a question regarding a piece of documentation on Temp Tables that I recently read on TechNet. The fourth paragraph of the Temporary Tables section on that page reads as follows:

If a temporary table is created with a named constraint and the temporary table is created within the scope of a user-defined transaction, only one user at a time can execute the statement that creates the temp table. For example, if a stored procedure creates a temporary table with a named primary key constraint, the stored procedure cannot be executed simultaneously by multiple users.

I work in an environment where we make significant use of a handful of stored procedures that use indexed temp tables, and we've never encountered an issue where users are having to wait for one execution to complete before the next begins. I hope that will continue to be the case, but I'm concerned that it could become an issue if this caveat is not properly understood.

Specifically, I am unclear on the following points:

  1. Does this apply only to global temp tables, or to local ones as well? It seems strange that a table that isn't visible outside of the session (as in the latter case) would prevent another session from executing simultaneously.
  2. What qualifies as a "named constraint"? Don't all constraints have names (even if they are system-generated)? Is this referring to constraints with a user-defined alias? This seems like poor phrasing to me.
  3. Does "multiple users" actually mean multiple sessions? These procedures are called through our application using a single service account, so 99.9% of calls to our scripts are made to the DB by that single account (and I'm unconcerned about the occasional call an admin may make on the backend). If the service account can run the sproc in multiple sessions simultaneously, then this issue is moot for my purposes.
  • 1
    You mention that your temp tables are indexed but the question is about contraints. Indexes are not constraints. What is true for one may or may not be true for the other. In this case, index names can be duplicated within a database, unlike constraints. Index names can not be duplicated on a single table. So named indexes will not cause the problems named constraints will. – Shannon Severance May 19 '17 at 23:15
  • @Shannon, indeed, at the time I wrote the question, I had this point confused. I think that the prolific use of PRIMARY KEY CLUSTERED vs. PRIMARY KEY that I've seen in sample code and documentation led me to believe that clustered indexes are constraints. And, by extension, to infer that all indexes are constraints. I did some light afternoon reading earlier which cleared this up for me. – Wesley Marshall May 19 '17 at 23:44
9

I think of it as you can't have any duplicate names in tempdb.sys.key_constraints. Here's what's in that metadata view on one of my servers:

initial view

All of the odd names that end with _6E... were names generated automatically by SQL Server. They are not named constraints because I did not explicitly give them a name when creating them. SQL Server generates a constraint name behind the scenes that in theory avoids name collisions.

If I try to create the following table in two different sessions:

create table #x1 (
ID INT NOT NULL,
CONSTRAINT NAMED_CONSTRAINT_1 PRIMARY KEY (ID)
);

The one that runs second throws an error:

Msg 2714, Level 16, State 5, Line 1

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

Msg 1750, Level 16, State 1, Line 1

Could not create constraint or index. See previous errors.

Checking out the view again:

with constraint

If I try to create the following table in two sessions there's no issue:

create table #y1 (
ID INT NOT NULL,
PRIMARY KEY (ID)
);

Here's the metadata view:

with default constraints

Just to answer your questions directly: the part that you quoted applies to both local and global temporary tables, a named constraint is one in which you deliberately give it a name, and multiple users means multiple sessions.

10

This applies to local temp tables.

The difference between named and unnamed constraints is this:

CREATE TABLE #t1 (c1 INT PRIMARY KEY CLUSTERED)

CREATE TABLE #t2 (c1 INT,
                     CONSTRAINT pk_c1 PRIMARY KEY  CLUSTERED(c1) )

Letting the system name constraints makes it extremely unlikely that there will be a collision. In this example, if you open two windows in SSMS, you'll be able to create #t1 in both, but not #t2.

Global temporary tables are shared by all users, so you have to handle things differently. They don't get 'destroyed' until the last session is done using them, so you need to make sure that when users access them, they can only access their data. This is sometimes done by SPID, other times by a hash value. It depends on how the global temp table is used.

Typically for global temp tables, stored procedures will check to see if they exist, and then only create them if the OBJECT_ID() is NULL.

Multiple users means multiple sessions. The login name has nothing to do with it. If George runs sp_something @i = 1 and Gina runs sp_something @i = 2, it doesn't matter if they're both logged in as User1, they'll have different SPIDs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.