Wann genau können mehrere Benutzer eine gespeicherte Prozedur nicht gleichzeitig mit einer temporären Tabelle ausführen?

9

Ich habe eine Frage zu einer Dokumentation zu temporären Tabellen, die ich kürzlich im TechNet gelesen habe . Der vierte Absatz des Abschnitts Temporäre Tabellen auf dieser Seite lautet wie folgt:

Wenn eine temporäre Tabelle mit einer benannten Einschränkung erstellt wird und die temporäre Tabelle im Rahmen einer benutzerdefinierten Transaktion erstellt wird, kann jeweils nur ein Benutzer die Anweisung ausführen, mit der die temporäre Tabelle erstellt wird. Wenn eine gespeicherte Prozedur beispielsweise eine temporäre Tabelle mit einer benannten Primärschlüsseleinschränkung erstellt, kann die gespeicherte Prozedur nicht gleichzeitig von mehreren Benutzern ausgeführt werden.

Ich arbeite in einer Umgebung, in der wir eine Handvoll gespeicherter Prozeduren verwenden, die indizierte temporäre Tabellen verwenden, und wir haben nie ein Problem festgestellt, bei dem Benutzer warten müssen, bis eine Ausführung abgeschlossen ist, bevor die nächste beginnt. Ich hoffe, dass dies auch weiterhin der Fall sein wird, aber ich befürchte, dass es zu einem Problem werden könnte, wenn diese Einschränkung nicht richtig verstanden wird.

Insbesondere bin ich in folgenden Punkten unklar:

  1. Gilt dies nur für globale temporäre Tabellen oder auch für lokale? Es scheint seltsam, dass eine Tabelle, die außerhalb der Sitzung nicht sichtbar ist (wie im letzteren Fall), die gleichzeitige Ausführung einer anderen Sitzung verhindert.
  2. Was ist eine "benannte Einschränkung"? Haben nicht alle Einschränkungen Namen (auch wenn sie vom System generiert wurden)? Bezieht sich dies auf Einschränkungen mit einem benutzerdefinierten Alias? Das scheint mir eine schlechte Formulierung zu sein.
  3. Bedeutet "mehrere Benutzer" tatsächlich mehrere Sitzungen? Diese Prozeduren werden über unsere Anwendung mit einem einzigen Dienstkonto aufgerufen, sodass 99,9% der Aufrufe unserer Skripte von diesem einzigen Konto an die Datenbank gesendet werden (und ich bin nicht besorgt über den gelegentlichen Anruf, den ein Administrator im Backend tätigen kann). Wenn das Dienstkonto den Sproc in mehreren Sitzungen gleichzeitig ausführen kann, ist dieses Problem für meine Zwecke nicht relevant.
Wesley Marshall
quelle
1
Sie erwähnen, dass Ihre temporären Tabellen indiziert sind, aber die Frage betrifft Einschränkungen. Indizes sind keine Einschränkungen. Was für das eine gilt, kann für das andere zutreffen oder nicht. In diesem Fall können Indexnamen im Gegensatz zu Einschränkungen innerhalb einer Datenbank dupliziert werden. Indexnamen können nicht in einer einzelnen Tabelle dupliziert werden. So benannte Indizes verursachen nicht die Probleme, die benannte Einschränkungen verursachen.
Shannon Severance
@ Shannon, in der Tat, als ich die Frage schrieb, hatte ich diesen Punkt verwirrt. Ich denke, dass die häufige Verwendung von PRIMARY KEY CLUSTERED im Vergleich zu PRIMARY KEY, die ich im Beispielcode und in der Dokumentation gesehen habe, mich zu der Annahme geführt hat, dass Clustered-Indizes Einschränkungen sind. Und im weiteren Sinne, um daraus zu schließen, dass alle Indizes Einschränkungen sind. Ich habe früher einen leichten Nachmittag gelesen, was das für mich geklärt hat.
Wesley Marshall

Antworten:

10

Ich denke daran, dass Sie keine doppelten Namen haben können tempdb.sys.key_constraints. In dieser Metadatenansicht auf einem meiner Server finden Sie Folgendes:

erste Ansicht

Alle ungeraden Namen, die mit enden, _6E...wurden automatisch von SQL Server generiert. Sie sind keine benannten Einschränkungen, da ich ihnen beim Erstellen nicht explizit einen Namen gegeben habe. SQL Server generiert hinter den Kulissen einen Einschränkungsnamen, der theoretisch Namenskollisionen vermeidet.

Wenn ich versuche, die folgende Tabelle in zwei verschiedenen Sitzungen zu erstellen:

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

Der zweite führt einen Fehler aus:

Nachricht 2714, Ebene 16, Status 5, Zeile 1

In der Datenbank befindet sich bereits ein Objekt mit dem Namen 'NAMED_CONSTRAINT_1'.

Meldung 1750, Ebene 16, Status 1, Zeile 1

Einschränkung oder Index konnten nicht erstellt werden. Siehe vorherige Fehler.

Überprüfen Sie die Ansicht erneut:

mit Einschränkung

Wenn ich versuche, die folgende Tabelle in zwei Sitzungen zu erstellen, gibt es kein Problem:

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

Hier ist die Metadatenansicht:

mit Standardeinschränkungen

Nur um Ihre Fragen direkt zu beantworten: Der von Ihnen angegebene Teil gilt sowohl für lokale als auch für globale temporäre Tabellen. Eine benannte Einschränkung ist eine, in der Sie ihr absichtlich einen Namen geben, und mehrere Benutzer bedeuten mehrere Sitzungen.

Joe Obbish
quelle
11

Dies gilt für lokale temporäre Tabellen.

Der Unterschied zwischen benannten und unbenannten Einschränkungen ist folgender:

CREATE TABLE #t1 (c1 INT PRIMARY KEY CLUSTERED)

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

Wenn Sie die Einschränkungen des Systemnamens zulassen, ist es äußerst unwahrscheinlich, dass es zu einer Kollision kommt. Wenn Sie in diesem Beispiel zwei Fenster in SSMS öffnen, können Sie in beiden Fenstern erstellen #t1, jedoch nicht #t2.

Globale temporäre Tabellen werden von allen Benutzern gemeinsam genutzt, sodass Sie die Dinge anders behandeln müssen. Sie werden erst zerstört, wenn die letzte Sitzung mit ihnen abgeschlossen ist. Sie müssen also sicherstellen, dass Benutzer nur dann auf ihre Daten zugreifen können, wenn sie darauf zugreifen. Dies erfolgt manchmal über SPID, manchmal über einen Hashwert. Dies hängt davon ab, wie die globale temporäre Tabelle verwendet wird.

In der Regel überprüfen gespeicherte Prozeduren bei globalen temporären Tabellen, ob sie vorhanden sind, und erstellen sie dann nur, wenn dies der Fall OBJECT_ID()ist NULL.

Mehrere Benutzer bedeuten mehrere Sitzungen. Der Login-Name hat nichts damit zu tun. Wenn George sp_something @i = 1und Gina laufen sp_something @i = 2, spielt es keine Rolle, ob beide als angemeldet sind User1, sie haben unterschiedliche SPIDs.

Erik Darling
quelle