Redgate Hub (Deutsch)

Temporäre Tabellen sind genau das. Sie werden am häufigsten verwendet, um einen Arbeitsbereich für die Zwischenergebnisse bereitzustellen, wenn Daten innerhalb eines Stapels oder einer Prozedur verarbeitet werden. Sie werden auch verwendet, um eine Tabelle von einer Tabellenwertfunktion zu übergeben, tabellenbasierte Daten zwischen gespeicherten Prozeduren zu übergeben oder in jüngerer Zeit in Form von Tabellenwertparametern ganze schreibgeschützte Tabellen von Anwendungen an SQL Server-Routinen zu senden oder übergeben Sie schreibgeschützte temporäre Tabellen als Parameter. Sobald ihre Verwendung abgeschlossen ist, werden sie automatisch verworfen.

Bevor wir uns zu tief mit der Technologie befassen, sollten Sie nach Möglichkeit Tabellenvariablen verwenden. Sie sind einfach und SQL Server erledigt die Arbeit für Sie. Sie neigen auch dazu, einem hart arbeitenden OLTP-System weniger Probleme zu bereiten. Nur gelegentlich müssen Sie sie möglicherweise optimieren, um eine gute Leistung in Joins zu erzielen. Ich werde dies jedoch gleich erläutern. Wenn Sie jedoch eine komplexere Verarbeitung temporärer Daten durchführen oder wahrscheinlich mehr als nur relativ kleine Daten verwenden Datenmengen in ihnen, dann sind lokale temporäre Tabellen wahrscheinlich die bessere Wahl.

Tabellenvariablen

Tabellenvariablen werden im Rahmen der Routine oder des Stapels verwendet, in dem sie sich befinden definiert und wurden ursprünglich erstellt, um Funktionen mit Tabellenwerten zu ermöglichen. Sie eignen sich jedoch für viele Zwecke, für die der traditionelle temporäre Tisch verwendet wurde. Sie verhalten sich wie andere Variablen in ihren Gültigkeitsbereichsregeln. Sobald sie nicht mehr im Geltungsbereich sind, werden sie entsorgt. Diese sind viel einfacher zu bearbeiten und ziemlich sicher. Außerdem lösen sie in den Routinen, in denen sie verwendet werden, weniger Neukompilierungen aus, als wenn Sie temporäre Tabellen verwenden würden. Tabellenvariablen erfordern weniger Sperrressourcen, da sie für den Prozess, der sie erstellt hat, „privat“ sind. Transaktions-Rollbacks wirken sich nicht auf sie aus, da Tabellenvariablen einen begrenzten Umfang haben und nicht Teil der persistenten Datenbank sind. Sie eignen sich daher zum Erstellen oder Speichern von Daten, die Rollbacks überstehen sollten, z. B. Protokolleinträge. Der Nachteil von Tabellenvariablen besteht darin, dass sie häufig entsorgt werden, bevor Sie ihren Inhalt zum Debuggen untersuchen oder sie verwenden können, um verschiedene SQL-Ausdrücke interaktiv auszuprobieren.

Wenn Ihre Anwendung konservativ ist und Ihre Datenmengen Sie beleuchten Ich werde nie etwas anderes wollen. Sie können jedoch auf Probleme stoßen. Eine Schwierigkeit besteht darin, dass Tabellenvariablen nur in ihrem lokalen Bereich referenziert werden können, sodass Sie sie nicht wie bei einer temporären Tabelle oder einem tabellenwertigen Parameter mit dynamischem SQL verarbeiten können. Dies liegt daran, dass Sie in dynamischem SQL keine extern definierte Tabellenvariable referenzieren können, die Sie dann über die EXEC-Anweisung oder die gespeicherte Prozedur sp_ExecuteSQL ausführen, da das dynamische SQL außerhalb des Bereichs ausgeführt wird der Tabellenvariablen. Sie können die Tabellenvariable natürlich in der dynamischen SQL erstellen und dann verwenden, da sich die Tabellenvariable im Gültigkeitsbereich befindet. Sobald das dynamische SQL ausgeführt wird, gibt es jedoch keine Tabellenvariable mehr.

Es sind auch einige Anomalien zu beachten. Sie können beispielsweise die Tabellendefinition nach der ersten DECLARE-Anweisung nicht ändern. In SQL Server 2000 kann eine Tabellenvariable nicht das Ziel einer SELECT INTO -Anweisung oder einer INSERT EXEC sein (jetzt behoben). Sie können keine benutzerdefinierten Funktionen aus CHECK-Einschränkungen, DEFAULT-Werten und berechneten Spalten in der Tabellenvariablen aufrufen. Die einzigen Einschränkungen, die Sie über die CHECK-Einschränkungen hinaus zulassen, sind PRIMARY KEY, UNIQUE KEY und NULL / NOT NULL.

Die schwierigsten Probleme treten jedoch mit zunehmender Größe der Tabellen auf, da vor SQL Server 2016 Sie konnten einen Index nicht explizit deklarieren, und für die Indizes, die die Einschränkungen UNIQUE und PRIMARY KEY erzwangen, wurden keine Verteilungsindizes verwaltet. Jetzt können Sie bestimmte Indextypen in Übereinstimmung mit der Tabellendefinition erstellen, die Verteilungsstatistiken werden jedoch noch nicht verwaltet. Der Abfrageoptimierer geht davon aus, dass die Tabelle nur eine Zeile enthält. Sie können auch keine parallelen Abfragepläne für einen SQL-Ausdruck generieren, der den Inhalt der Tabelle ändert. Um die Indexbeschränkung teilweise zu umgehen, können Sie Einschränkungen verwenden, um dasselbe zu tun. Am wichtigsten ist die Primärschlüsseleinschränkung, mit der Sie einen Clustered-Index festlegen können. Für die Leistung sind jedoch eindeutige Einschränkungen hilfreich. Der Abfrageoptimierer verwendet sie gerne, wenn sie vorhanden sind.

Das größte Problem bei Tabellenvariablen besteht darin, dass keine Statistiken für die Spalten verwaltet werden. Dies bedeutet, dass der Abfrageoptimierer die Größe und Verteilung der Daten erraten muss. Wenn dies falsch ist, wird bei Joins eine schlechte Leistung festgestellt: In diesem Fall können Sie nur wenig anderes tun als zur Verwendung klassischer lokaler temporärer Tabellen zurückzukehren. Ab SQL Server 2019 hat Microsoft eine neue Funktion namens Table Variable Deferred Compilation eingeführt, mit der dieses Problem behoben wird. Um mehr zu erfahren, lesen Sie diesen Artikel von Greg Larsen.

Wenn Sie SQL Server 2019 nicht verwenden, können Sie versuchen, der Anweisung OPTION (RECOMPILE) hinzuzufügen, bei der die Tabellenvariable mit anderen Tabellen verknüpft wird. Auf diese Weise kann SQL Server die Anzahl der Zeilen beim erneuten Kompilieren ermitteln, da die Zeilen bereits ausgefüllt wurden. Dies löst das Problem nicht vollständig, da der Optimierer noch keine Verteilungsstatistik hat und normalerweise, wenn die Verteilung verzerrt ist, einen schlechten Plan erstellen kann. In dieser Demo wurde der Join durch Hinzufügen der Option OPTION (RECOMPILE) um drei Viertel reduziert.

Wenn Sie nun festlegen können, was in den Tabellen enthalten ist, können Sie eine Primärschlüsseleinschränkung für diese verwenden Tabellen. Auf diese Weise konnte der Optimierer anstelle eines Tabellenscans eine Clustered-Index-Suche verwenden, und die Ausführungszeit war zu schnell, um

zu messen. Beginnen Sie mit Tabellenvariablen, verwenden Sie jedoch wieder lokale temporäre Tabellen, wenn Sie auf Leistungsprobleme stoßen. Einige Leute sind mutig genug, um Ratschläge bezüglich der Anzahl der Zeilen in einer Tabelle zu geben, und ich habe gesehen, dass maximal 100 oder 1000 angeboten werden. Ich habe jedoch gesehen, dass weitaus größere Tabellenvariablen im Laufe der Zeit vollkommen zufriedenstellend funktionieren und weitaus kleinere Probleme bereiten. In kleineren Tabellen ist das Problem jedoch weniger erkennbar!

Tabellenwertparameter

Der Tabellenwertparameter (TVP) ist ein spezieller Typ von Tabellenvariablen, der seine Verwendung erweitert. Wenn Tabellenvariablen als Parameter übergeben werden, wird die Tabelle in der TempDB-Systemdatenbank als Tabellenvariable materialisiert und als Referenz übergeben, ein Zeiger auf die Tabelle in der TempDB.

Seitdem wurden tabellenwertige Parameter verwendet SQL Server 2008 zum Senden mehrerer Datenzeilen an eine Transact-SQL-Routine oder an einen Stapel über sp_ExecuteSQL. Ihr besonderer Wert für den Programmierer besteht darin, dass sie innerhalb von TSQL-Code als verwendet werden können Sie eignen sich daher gut zum Senden von Client-Tabellen an den Server. In TSQL können Sie Variablen mit Tabellenwerten deklarieren, Daten in sie einfügen und diese Variablen als Parameter mit Tabellenwerten an gespeicherte Prozeduren und Funktionen übergeben. Ihre allgemeinere Nützlichkeit wird durch die Tatsache eingeschränkt, dass sie nur als schreibgeschützt übergeben werden. Sie können keine UPDATE, DELETE oder INSERT Anweisungen für eine Tabelle ausführen Parameter im Hauptteil einer Routine.

Sie müssen einen benutzerdefinierten Tabellentyp erstellen und eine Tabellenstruktur definieren, um sie zu verwenden. Hier ist ein einfaches Beispiel für ihre Verwendung in TSQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

/ * Zuerst müssen Sie eine Tabelle erstellen Art. * /
CREATE TYPE-Namen ALS TABELLE
(Name VARCHAR (10));
GO
/ * Erstellen Sie als Nächstes eine Prozedur, um Daten für den Tabellenwertparameter, die Namenstabelle, zu empfangen, und wählen Sie ein Element aus der Tabelle aus * /
VERFAHREN ERSTELLEN ChooseAName
@CandidateNames Names READONLY
AS
DECLARE @candidates TABLE (NAME VARCHAR (10),
theOrder UNIQUEIDENTIFIER)
INSERT IN @candidates (name, theorder)
SELECT name, NEWID ()
FROM @CandidateNames
SELECT TOP 1
NAME
FROM @Candidates
ORDER BY theOrder
GO
/ * Deklarieren Sie eine Variable, die auf den Typ für unsere Liste der Kühe verweist. * /
DECLARE @MyFavouriteCowName AS Names;
/ * Fügen Sie der Tabellenvariablen Daten hinzu. * /
INSERT IN @MyFavouriteCowName (Name)
SELECT „Bossy“ UNION SELECT „Bessy“ UNION SELECT „Blütenblatt“ UNION SELECT „Daisy“ UNION SELECT „Lulu“ UNION SELECT “ Butterblume „UNION SELECT“ Bertha „UNION SELECT“ Bubba „UNION SELECT“ Beauregard „UNION SELECT“ Brunhilde „UNION SELECT“ Lore „UNION SELECT“ Lotte „UNION SELECT“ Rosa „UNION SELECT“ Thilde „UNION SELECT“ Lisa „UNION SELECT“ Peppo „UNION SELECT“ Maxi „UNION SELECT“ Moriz „UNION SELECT“ Marla „
/ * Übergeben Sie die Tabelle mit der Liste der traditionellen Nemes von Kühen an die gespeicherte Prozedur. * /
EXEC selectAName @MyFavouriteCowName
GO

Wie bei Tabellenvariablen existiert der tabellenwertige Parameter nicht mehr, sobald er außerhalb des Gültigkeitsbereichs liegt, aber die Typdefinition bleibt bestehen, bis er explizit gelöscht wird.Wie Tabellenvariablen erhalten sie keine Sperren, wenn die Daten von einem Client ausgefüllt werden, und Statistiken werden nicht für Spalten mit tabellenwertigen Parametern verwaltet. Sie können keinen tabellenwertigen Parameter als Ziel einer SELECT INTO oder INSERT EXEC -Anweisung verwenden. Wie zu erwarten, kann sich ein tabellenwertiger Parameter in der FROM -Klausel von SELECT INTO oder in der Zeichenfolge oder gespeicherte Prozedur.

Der TVP löst das häufig auftretende Problem, eine lokale Variable an dynamisches SQL übergeben zu wollen, das dann von einem sp_ExecuteSQL. Es ist von Microsoft schlecht dokumentiert, daher zeige ich Ihnen ein Beispiel, um Ihnen den Einstieg zu erleichtern.

Bevor wir die traditionelleren temporären Tabellen und ihre Verwendung beschreiben, müssen wir uns mit den folgenden Themen befassen Ort, an dem temporäre Tische gehalten werden. TempDB.

TempDB

Temporäre Tabellen und Tabellenvariablen werden in der TempDB-Datenbank erstellt, die eigentlich nur eine weitere Datenbank mit einfacher Wiederherstellung ist: Mit TempDB wird nur eine ausreichende minimale Protokollierung durchgeführt Rollback und andere ACID-Feinheiten zu ermöglichen. Der besondere Unterschied von TempDB besteht darin, dass alle Objekte wie Tabellen beim Start gelöscht werden. Da TempDB immer das einfache Wiederherstellungsmodell verwendet, wird die abgeschlossene Transaktion am nächsten TempDB-Prüfpunkt aus dem Protokollprotokoll gelöscht und nur die Live-Transaktionen werden beibehalten. Dies alles bedeutet, dass temporäre Tabellen sich wie jede andere Art von Basistabelle verhalten, indem sie protokolliert und genau wie sie gespeichert werden. In der Praxis bleiben temporäre Tabellen wahrscheinlich im Speicher zwischengespeichert, jedoch nur, wenn sie häufig verwendet werden: wie bei einer Basistabelle. TempDB betreibt ein System namens temporäre Objektwiederverwendung, das einen Teil der temporären Objekte mit dem Plan zwischenspeichert, wenn genügend Speicher vorhanden ist. Dies kann für die Legende verantwortlich sein, dass temporäre Objekte nur im Speicher vorhanden sind. Die Wahrheit ist wie immer „es kommt darauf an …“.

In TempDB passieren viele andere Dinge: Das Datenbankmodul kann es zum Platzieren von Arbeitstabellen für DBCC-Prüfungen, zum Erstellen oder Neuerstellen von Indizes, Cursorn, verwenden. zum Beispiel. Zwischentabellen in Abfragen, die als „Hashes“, „Sortierungen“ und „Spools“ bezeichnet werden, werden beispielsweise in TempDB zusammen mit denjenigen materialisiert, die für mehrere „physische“ Operationen bei der Ausführung von SQL-Anweisungen erforderlich sind. Es wird auch als Versionsspeicher für Snapshot-Isolation, MARS (Multiple Active Results Sets), Trigger und Online-Indexerstellung verwendet.

Da temporäre Tabellen genau wie Basistabellen gespeichert werden, gibt es eine oder zwei Dinge, vor denen Sie vorsichtig sein müssen. Sie müssen beispielsweise über die Berechtigung CREATE TABLE in TempDB verfügen, um eine normale Tabelle erstellen zu können. Um Ihnen die Mühe zu ersparen, wird dies standardmäßig der DBO-Rolle (Datenbankbesitzer) zugewiesen. Möglicherweise müssen Sie dies jedoch explizit für Benutzer tun, denen die DBO-Rolle nicht zugewiesen ist. Alle Benutzer haben die Berechtigung, lokale oder globale temporäre Tabellen in TempDB zu erstellen, da diese ihnen über den Benutzersicherheitskontext GUEST zugewiesen werden.

Die klassische temporäre Tabelle kommt herein Zwei Varianten: die globale oder gemeinsam nutzbare temporäre Tabelle mit dem Präfix ## und die lokale temporäre Tabelle, deren Name mit dem Präfix # versehen ist. Die lokalen temporären Tabellen ähneln weniger normalen Tabellen als die globalen temporären Tabellen: Sie Sie können keine Ansichten für sie erstellen oder ihnen Trigger zuordnen. Es ist etwas schwierig herauszufinden, welcher Prozess, welche Sitzung oder welche Prozedur sie erstellt hat. Wir werden Ihnen später dabei helfen. Am wichtigsten ist, dass sie sicherer sind als eine globale temporäre Tabelle, da nur der Eigentümerprozess sie sehen kann.

Eine weitere Kuriosität der lokalen temporären Tabelle (und der lokalen temporären gespeicherten Prozedur) besteht darin, dass sie einen anderen Namen hat in den Metadaten zu denen, die Sie in Ihrer Routine oder im Stapel angeben. Wenn dieselbe Routine gleichzeitig von mehreren Prozessen ausgeführt wird, muss das Datenbankmodul in der Lage sein, zwischen den identischen lokalen temporären Tabellen zu unterscheiden, die von den verschiedenen Prozessen erstellt wurden. Dazu wird jedem lokalen temporären Tabellennamen eine numerische Zeichenfolge hinzugefügt, die durch Unterstriche links aufgefüllt wird. Obwohl Sie den Kurznamen wie #MyTempTable angeben, besteht das, was tatsächlich in TempDB gespeichert ist, aus dem Tabellennamen, der in der Anweisung CREATE TABLE angegeben ist und das Suffix. Aufgrund dieses Suffixes dürfen lokale temporäre Tabellennamen maximal 116 Zeichen lang sein.

Wenn Sie sehen möchten, was gerade passiert, können Sie die Tabellen in TempDB genauso anzeigen wie alle anderen Tabelle. Sie können sogar sp_help nur dann für temporäre Tabellen verwenden, wenn Sie sie über TempDB aufrufen.

ausführen tr>

1
2
3

USE TempDB
go
sp_Help #mytemp

oder Sie finden sie in den Systemansichten von TempDB, ohne die Datenbanken zu wechseln.

1

SELECT name, create_date FROM TempDB.sys.tables WHERE Name LIKE „#%“

Oder das Informationsschema

1

SELECT * FRO M TempDB.information_schema.tables

Noch besser, Sie können Finden Sie heraus, welcher Prozess und welcher Benutzer an riesigen temporären Tabellen in TempDB festhält und sich weigert, den Speicherplatz aufzugeben.

Sie können benutzerdefinierte Datentypen in temporären Tabellen nur verwenden, wenn die Datentypen in TempDB vorhanden sind. Das heißt, es sei denn, die Datentypen wurden explizit erstellt.

Benutzertabellen in TempDB

Bei normaler Verwendung erstellen Sie temporäre Tabellen oder Tabellenvariablen, ohne zu tief darüber nachzudenken. Es ist jedoch interessant, dass TempDB für jede Art von Sandbox-Aktivität verfügbar ist. Sie können normale Basistabellen, Ansichten oder alles andere erstellen, was Sie möchten. Sie können Schemas, gespeicherte Prozeduren usw. erstellen. Es ist unwahrscheinlich, dass Sie dies tun möchten, aber es ist sicherlich möglich, da TempDB nur eine andere Datenbank ist. Ich musste nur meinen Entwicklungs-SQL Server neu starten, nachdem ich mir dies durch die Installation von AdventureWorks bewiesen hatte. Dies bedeutet, dass es möglich ist, eine Basistabelle in TempDB zu erstellen, eine Art ..er… temporäre permanente Tabelle. Im Gegensatz zur globalen temporären Tabelle müssten Sie Ihre gesamte Hausarbeit selbst erledigen: Sie sind allein. Gleiches gilt für Routinen. Dies hat den Vorteil, dass bei jeder Verarbeitung die einfache Wiederherstellung von TempDB verwendet wird, sodass SQL Server beim nächsten Start als Mutter fungiert, wenn Sie nicht aufwischen. Dies kann jedoch sehr lange dauern. Die nächste Stufe besteht darin, eine so genannte „persistente temporäre“ Tabelle zu haben. In dieser Tabelle sind die Daten selbst beim Neustart des Servers flüchtig, die Tabelle selbst bleibt jedoch bestehen. Die wahrscheinlich häufigste Methode zum Erstellen einer dauerhaften temporären Tabelle besteht darin, beim Start eine globale temporäre Tabelle neu zu erstellen. Dies kann automatisch erfolgen, wenn alle Datenbanken wiederhergestellt sind und die Meldung „Wiederherstellung abgeschlossen“ protokolliert wird. Obwohl dies eine „globale temporäre“ Meldung ist, wird sie nicht gelöscht, wenn alle Verbindungen, die sie verwenden, verschwunden sind, da der Prozess, der sie ausführt verschwindet nie. Es ist wahrscheinlich besser, diese Art von Arbeitstabelle in der Datenbank zu erstellen, in der sie verwendet wird. Wenn Sie jedoch die vollständige Wiederherstellung verwenden, bleibt die temporäre Arbeit im Protokoll. Sie können natürlich auch eine normale Arbeit erstellen Tabelle in TempDB. Sie können diese persistenten Tabellen beim Start erstellen, indem Sie eine gespeicherte Prozedur im Master definieren, die die globale temporäre Tabelle erstellt.

Warum diese Art von Hybridtabelle verwenden? Es gibt beispielsweise eine Zahl von Techniken zum Übergeben von Tabellen zwischen Prozeduren über persistente Tabellen auf multiprozesssichere Weise, um eine Reihe von Verarbeitungen für die Daten durchzuführen. Diese werden als prozessschlüsselte Tabellen bezeichnet (siehe Teilen von Daten zwischen gespeicherten Prozeduren) : Process-Keyed-Tabelle von Erland Sommarskog ). Sie ziehen anfangs die Augenbrauen eines erfahrenen DBA hoch, sind jedoch eine effektive und sichere Lösung für ein mehrjähriges Problem, wenn sie ordnungsgemäß ausgeführt werden.

Neben temporären Tabellen gibt es auch eine Reihe von Tabellentypen Diese werden nicht direkt von Basistabellen abgeleitet, wie z. B. „gefälschten“ Tabellen und abgeleiteten Tabellen. Einige davon sind so flüchtig, dass sie am besten als kurzlebig und nicht als vorübergehend angesehen werden. Der CTE verwendet kurzlebige Tabellen, die „inline“ oder „abgeleitet“ sind und nicht materialisiert werden. BOL bezeichnet sie als „temporär benannte Ergebnismengen“. Sie existieren nur im Rahmen des Ausdrucks. In einem CTE haben sie gegenüber abgeleiteten Tabellen den Vorteil, dass auf sie mehrmals zugegriffen werden kann.

Lokale temporäre Tabelle

Mit lokaler temporärer Tabelle (Namen, die mit # beginnen), Was unter der Haube vor sich geht, ist überraschend ähnlich wie Tabellenvariablen. Wie bei Tabellenvariablen sind lokale temporäre Tabellen für den Prozess, der sie erstellt hat, privat. Sie können daher nicht in Ansichten verwendet werden, und Sie können ihnen keine Trigger zuordnen.

Sie sind handlicher als Tabellenvariablen, wenn Sie SELECT INTO verwenden möchten, um sie zu erstellen, aber ich bin etwas vorsichtig bei der Verwendung von SELECT INTO In einem System, das wahrscheinlich geändert werden muss, möchte ich meine temporären Tabellen lieber explizit zusammen mit allen erforderlichen Einschränkungen erstellen.

Sie können nicht leicht feststellen, welche Sitzung oder Prozedur erstellt wurde diese Tabellen. Dies liegt daran, dass das Datenbankmodul in der Lage sein muss, dieselben Tabellen zu unterscheiden, die von den verschiedenen Prozessen erstellt wurden, wenn dieselbe gespeicherte Prozedur gleichzeitig von mehreren Prozessen ausgeführt wird. Das Datenbankmodul führt dazu intern ein links aufgefülltes numerisches Suffix an jeden lokalen temporären Tabellennamen an. Der vollständige Name einer temporären Tabelle, wie er in der Ansicht sys.objects in TempDB gespeichert ist, setzt sich aus dem in der Anweisung CREATE TABLE angegebenen Tabellennamen und dem vom System generierten numerischen Suffix zusammen. Um das Suffix zu berücksichtigen, muss der für einen lokalen temporären Namen angegebene Tabellenname weniger als 116 Zeichen enthalten.

Sie erhalten eine Verwaltung mit lokalen temporären Tabellen. Sie werden automatisch gelöscht, wenn sie den Gültigkeitsbereich verlassen, es sei denn, sie werden explizit mit DROP TABLE gelöscht. Ihr Umfang ist großzügiger als der einer Tabellenvariablen, sodass Sie keine Probleme haben, sie in Stapeln oder in dynamischem SQL zu referenzieren. Lokale temporäre Tabellen werden am Ende der aktuellen Sitzung oder Prozedur automatisch gelöscht. Das Löschen am Ende der Prozedur, die es erstellt hat, kann zu Kopfkratzern führen: Eine lokale temporäre Tabelle, die in einer gespeicherten Prozedur oder Sitzung erstellt wurde, wird nach Abschluss gelöscht, sodass der Prozess, der die gespeicherte Prozedur aufgerufen hat, nicht auf sie verweisen kann hat die Tabelle erstellt. Es kann jedoch von allen verschachtelten gespeicherten Prozeduren referenziert werden, die von der gespeicherten Prozedur ausgeführt werden, die die Tabelle erstellt hat. Wenn die verschachtelte Prozedur auf eine temporäre Tabelle verweist und zu diesem Zeitpunkt zwei temporäre Tabellen mit demselben Namen vorhanden sind, gegen welche Tabelle wird die Abfrage aufgelöst?

Aus Neugier können Sie auch lokale temporäre gespeicherte Prozeduren mit erstellen den gleichen Umfang und die gleiche Lebensdauer wie eine lokale temporäre Tabelle. Sie können dies nicht für andere Routinen tun.

Globale temporäre Tabellen.

Wie lokale temporäre Tabellen werden globale temporäre Tabellen (sie beginnen mit ##) automatisch gelöscht, wenn die Sitzung endet, in der die Tabelle erstellt wurde: Allerdings, weil globale Tabellen Sie sind für den Prozess, der sie erstellt hat, nicht privat, sondern müssen danach bestehen bleiben, bis die letzte Transact-SQL-Anweisung, die zum Zeitpunkt des Endes der Erstellungssitzung aktiv auf die Tabelle verwiesen hat, die Ausführung beendet hat und die Sperren aufgehoben werden. Jeder, der zum Zeitpunkt der Existenz dieser globalen temporären Tabellen Zugriff auf TempDB hat, kann diese temporären Objekte direkt abfragen, ändern oder löschen.

Sie können temporären Tabellen Regeln, Standardeinstellungen und Indizes zuordnen, aber keine Ansichten erstellen auf temporären Tabellen oder assoziieren Sie Trigger mit ihnen. Sie können beim Erstellen einer temporären Tabelle nur dann einen benutzerdefinierten Datentyp verwenden, wenn der Datentyp in TempDB vorhanden ist.

Gespeicherte Prozeduren können auf temporäre Tabellen verweisen, die während der aktuellen Sitzung erstellt wurden. Innerhalb einer gespeicherten Prozedur können Sie keine temporäre Tabelle erstellen, löschen und dann eine neue temporäre Tabelle mit demselben Namen erstellen.

Obwohl dies funktioniert …

… funktioniert dies nicht. t

1
2
3
4
5
6
7
8
9
10
11
12

VERFAHREN ERSTELLEN Fehlverhalten bei temporären Tabellen AS
CREATE Tabelle #Color (
Color varchar (10) PRIMARY key)
INSERT IN #color SELECT „Rot“ UNION SELECT „Weiß“
UNION SELECT „grün „UNION SELECT“ Gelb „UNION SELECT“ blau „
DROP TABLE #color
CREATE-Tabelle #Color (
Color varchar (10) PRIMARY key)
INSERT IN #color SELECT „Rot“ UNION SELECT „Weiß“
UNION SELECT „grün „UNION SELECT“ Gelb „UNION SELECT“ blau „
DROP TABLE #color
go

Mithilfe lokaler temporärer Tabellen können Sie die gespeicherte Prozedur bei jeder Verwendung unbeabsichtigt neu kompilieren. Dies ist nicht gut, da es unwahrscheinlich ist, dass die gespeicherte Prozedur eine gute Leistung erbringt. Um eine Neukompilierung zu vermeiden, sollten Sie nicht auf eine temporäre Tabelle verweisen, die in einer aufrufenden oder aufgerufenen gespeicherten Prozedur erstellt wurde: Wenn Sie dies nicht können, fügen Sie die Referenz in eine Zeichenfolge ein, die dann mit EXECUTE Anweisung oder sp_ExecuteSQL gespeicherte Prozedur. Stellen Sie außerdem sicher, dass die temporäre Tabelle in der gespeicherten Prozedur oder im Trigger erstellt wird, bevor auf sie verwiesen und nach diesen Verweisen gelöscht wird.Erstellen Sie keine temporäre Tabelle in einer Flow-of-Flow-Anweisung wie IF... ELSE oder WHILE.

Sie dürfen globale temporäre gespeicherte Prozeduren erstellen, aber ich habe noch keine Verwendung für sie gefunden. Globale temporäre Funktionen sind nicht zulässig.

Schlussfolgerungen

Seien Sie auf einem gemeinsamen Spielplatz sehr vorsichtig, wie Sie diesen Schläger schwingen. Während Sie dies lesen, haben Sie festgestellt, dass in TempDB eine Menge Aktivität stattfindet, und Sie können den gesamten SQL Server verwüsten, indem Sie lang laufende Prozesse verwenden, die temporäre Tabellen, unabhängig vom Typ, mit unnötigen Mengen füllen Daten. Tatsächlich habe ich Ihnen in diesem Artikel Hinweise gegeben, wie Sie Ihren DBA wirklich, wirklich verärgern können, indem Sie diese wertvolle gemeinsam genutzte Ressource, die TempDB, rücksichtslos verwenden. (In den alten Tagen vor S2005 war die Verwendung von SELECT INTO mit einem riesigen Tisch die große Vergeltungswaffe.

Ich bin immer vorsichtig, wenn ich über- Allgemeiner Rat, aber ich bevorzuge immer, dass meine Datenbanken Tabellenvariablen und TVPs verwenden, wo immer dies möglich ist. Sie erfordern weniger Ressourcen und es ist weniger wahrscheinlich, dass Sie daran festhalten, wenn Sie mit ihnen fertig sind. Ich verwende sie gerne maximal Mit Spalten- und Tabellenprüfungen und -einschränkungen. Es kann vorkommen, dass ihnen der Dampf ausgeht, insbesondere wenn die Tabellengröße größer wird. In solchen Fällen oder wenn es aufgrund ihres eingeschränkten Bereichs nicht praktikabel ist, Tabellenvariablen zu verwenden Ich werde lokale temporäre Tabellen verwenden. Es dauert eine Menge gespitzter Lippen und Kopfschütteln, bis ich einer globalen temporären Tabelle oder einer dauerhaften temporären Tabelle zustimme. Sie haben einige gültige und absolut vernünftige Verwendungszwecke, aber sie verlassen sich auf die Programmierer für die notwendige Reinigung

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.