Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create PK for #temp table failed when the script is run in parallel

I have the following code in a stored procedure.

....
select ... into #temp from ....
alter table #temp add constraint PK_mytemp13 primary key (....)
....

And I will get the following error message from time to time if the stored procedure is run in parallel.

There is already an object named 'PK_perf322dsf' in the database. Could not create constraint. See previous errors.

I think it can be avoid by the following approaches. Is there any other more elegant solution?

  1. Create a temp table with primary key first. Then insert the rows.
    create table #temp (... primary key (....))

  2. Create PK dynamically with session id dynamically.
    declare @s varchar(500) = 'alter table #temp add constraint PK_temp' + @@spid + ' primary key (....)

like image 231
ca9163d9 Avatar asked Jan 16 '12 08:01

ca9163d9


1 Answers

This can only happen if the same client connection instantiation (which equals one SPID or connection in SQL Server) is being re-used for 2 different calls. Two parallel calls should have different connection instantiations and separate SPIDs

SPIDs are completely isolated from each other with local (single #temp tables)

Edit:

Ignore above

I've never named constraints on temp tables before. I use indexes as I need them or just add PRIMARY KEY after the column. Constraint names are database-unique in sys.objects

A PK is basically a non-unique clustered index. So use CREATE UNIQUE CLUSTERED INDEX instead as index names are unique per table in sys.indexes.

This fails when run in 2 SSMS Query windows

CREATE TABLE #gbn (foo int NOT NULL);
ALTER TABLE #gbn ADD CONSTRAINT PK_gbn PRIMARY KEY (foo);

Msg 2714, Level 16, State 5, Line 2
There is already an object named 'PK_gbn' in the database.
Msg 1750, Level 16, State 0, Line 2
Could not create constraint. See previous errors.

Curiously, the error and the constraint name match unlike your error

This works

CREATE TABLE #gbn (foo int NOT NULL);
CREATE UNIQUE CLUSTERED INDEX PK_gbn ON #gbn (foo);
like image 93
gbn Avatar answered Sep 21 '22 14:09

gbn