Es gibt Dinge, die tut man einfach nicht. Ja, wirklich, da gibt es weltweite ungeschrieben Gesetze. Zum Beispiel nimmt man keine Stifte von anderen Leuten mit und von Kollegen schon gleich gar nicht. Dennoch passiert sowas immer wieder.

Genauso benutzt man in Prozeduren keine temporären Tabellen. Außer vielleicht in wenigen Ausnahmen, wo der Overhead kaum ins Gewicht fällt und sogar die Abläufe etwas vereinfacht. Aber auf diese Tabellen legt man keine benannten Constraints an. Warum auch? Will man die separat wieder entfernen können? Wenn überhaupt, dann also bitte nur "inline". Wer anderer Meinung ist, der möge weiter lesen…

Der Name von benannte Constraints muss auch auf temporären Tabellen datenbank-weit eindeutig sein. Wenn die Prozedur also parallel ausgeführt wird (dafür sind Prozeduren ja da), dann knallt es. Folgender Code in zwei Session gleichzeitig ausgeführt, ist ungesund:
IF object_id('tempdb..#bla') IS NOT NULL
DROP TABLE #bla

CREATE TABLE #bla
(ID int)

ALTER TABLE #bla
ADD CONSTRAINT c_bla_check CHECK (ID > 0)

In der zweiten Sitzung kommen dann diese netten Meldungen:

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

Das passiert mit jedem benannten Constraint, auch mit Fremd- und Primärschlüsseln – bei Indexen hingegen nicht. Dabei spricht wenig gegen anständige "inline" definierte Constraints in temporären Tabellen (außer der Performance, die verbraten wird, natürlich):

IF object_id('tempdb..#bla') IS NOT NULL
DROP TABLE #bla

CREATE TABLE #bla
(ID int
CHECK (ID > 0))

Diesen Hinweis bekam ich übrigens von meinem Kollegen Markus. Danke!