2009-05-13 17 views
26

Ich habe über temporäre Tabellen in sp Fragen und wie all das Nebenläufigkeit beeinflussen können. SP wurde auf einem MSSQL 08-Server erstellt.Temporäre Tabellen in gespeicherten Prozeduren

Wenn ich einen SP, wo ich eine temporäre Tabelle erstellen und legen Sie es wieder so:

BEGIN 

CREATE TABLE #MyTempTable 
(
    someField int, 
    someFieldMore nvarchar(50) 
) 

... Use of temp table here 
... And then.. 

DROP TABLE #MyTempTable 

END 

wird dieser SP sehr sehr oft aufgerufen werden, so meine Frage ist, kann es Concurrency Probleme jemals hier auftreten?

Antwort

28

Nein. Unabhängige Instanzen der temporären Tabelle werden für jede Verbindung erstellt.

+0

Okay, das ist auch das, was ich dachte .. ich nervös, weil ich Query Analyzer wurde mit und bauen eine temporäre Tabelle und konnte es nennen später wieder, als ich es nicht fallen gelassen habe. Aber im Lichte Ihrer Post habe ich versucht, eine neue Abfrage zu öffnen und versuchte es von dort ohne Erfolg und jetzt bin ich wieder ruhig :) –

+0

Aber Leistung weise gibt es große Nebenläufigkeit Probleme. – tpower

+1

@tpower: Mein Verständnis von OP war hauptsächlich über das Ändern von gemeinsamen Status und Threading-Problemen. Es ist offensichtlich, dass die Leistung beeinträchtigt wird. –

17

Vielleicht.

Temporäre Tabellen mit einem Präfix # (#beispiel) werden pro Sitzung beibehalten. Wenn der Code die gespeicherte Prozedur erneut aufruft, während ein anderer Aufruf ausgeführt wird (z. B. Hintergrundthreads), schlägt der Erstellungsaufruf fehl, da er bereits vorhanden ist.

Wenn Sie wirklich eine Tabelle Variable

DECLARE @MyTempTable TABLE 
(
    someField int, 
    someFieldMore nvarchar(50) 
) 

statt besorgt verwenden Dies wird auf die „Instanz“ des Stored Procedure Call spezifisch sein.

+2

Sie können die SQL-Sitzung nicht erneut verwenden, unabhängig davon, was der Client versucht. – gbn

+0

"(#beispiel) werden pro Sitzung beibehalten" Und Sitzungen basieren auf einer Verbindung? –

+0

Okay danke für diese Vereinheitlichung gbn –

7

Nicht wirklich und ich spreche über SQL Server. Die temporäre Tabelle (mit single #) existiert und ist in dem Bereich sichtbar, in dem sie erstellt wird (bereichsgebunden). Jedes Mal, wenn Sie Ihre gespeicherte Prozedur aufrufen, wird ein neuer Bereich erstellt, und daher ist diese temporäre Tabelle nur in diesem Bereich vorhanden. Ich glaube, dass die temporären Tabellen auch für gespeicherte Prozeduren und UDFs sichtbar sind, die auch in diesem Bereich aufgerufen werden. Wenn Sie jedoch double pound (##) verwenden, werden sie innerhalb Ihrer Sitzung global und daher für andere ausführende Prozesse als Teil der Sitzung sichtbar, in der die temporäre Tabelle erstellt wird, und Sie müssen überlegen, ob auf die temporäre Tabelle zugegriffen werden kann gleichzeitig ist wünschenswert oder nicht.

-1

Die Datenbank verwendet dieselbe Sperre für alle #temp-Tabellen. Wenn Sie also eine Menge verwenden, erhalten Sie Deadlock-Probleme. Es ist besser, @ table-Variablen für die Parallelität zu verwenden.

+1

-1 Die Sperre Sache war nicht wahr seit SQL Server 6.5 –

-1

Verwenden Sie @temp-Tabellen wann immer möglich - das heißt, Sie benötigen nur einen Primärschlüssel und Sie müssen nicht auf die Daten von einem untergeordneten gespeicherten Prozess zugreifen.

Verwenden Sie #temp-Tabellen, wenn Sie auf die Daten von einem untergeordneten gespeicherten proc zugreifen müssen (es ist eine schlechte globale Variable für die gespeicherte proc-Aufrufkette) und Sie haben keine andere saubere Möglichkeit, die Daten zwischen gespeicherten Procs zu übergeben. Auch verwenden, wenn Sie einen Sekundärindex müssen (obwohl, wirklich sich fragen, ob es sich um eine #temp Tabelle ist, wenn Sie mehr als ein Index benötigen)

Wenn Sie dies tun, immer erklären Ihre #temp Tabelle an der Spitze der Funktion. SQL wird eine Neukompilierung Ihres gespeicherten Proc erzwingen, wenn es die create table -Anweisung sieht .... wenn Sie also die # temp -Tabellen-Deklaration in der Mitte des gespeicherten proc haben, müssen Sie den gespeicherten proc-Prozess stoppen und neu kompilieren.

+1

-1 Nein, temporäre Objekte (Tabellen und Variablen) sind in der Regel in SQL Server 2005 und später zwischengespeichert, so Neukompilierung wird vermieden. Siehe http://sqlblog.com/blogs/paul_white/archive/2012/08/17/temporary-object-caching-explained.aspx und http://technet.microsoft.com/de-us/library/cc966545.aspx zum Beispiel –

0

Nach SQL Server 2008-Bücher Sie können lokale und globale temporäre Tabellen erstellen. Lokale temporäre Tabellen sind nur in der aktuellen Sitzung sichtbar und globale temporäre Tabellen sind für alle Sitzungen sichtbar.

‚#table_temporal

‘ ## table_global

Wenn eine lokale temporäre Tabelle in einer gespeicherten Prozedur oder Anwendung erstellt, die gleichzeitig von mehreren Benutzern ausgeführt werden können, muss der Datenbank-Engine der Lage sein, um die von den verschiedenen Benutzern erstellten Tabellen zu unterscheiden. Das Datenbankmodul führt dies durch internes Anhängen eines numerischen Suffixes an jeden lokalen temporären Tabellennamen aus.

Dann gibt es kein Problem.

2

Für alle, die Tabellenvariablen verwenden, sollten Sie vorsichtig sein. Tabellenvariable kann nicht indexiert werden, während eine temporäre Tabelle sein kann. Eine Tabellenvariable ist am besten, wenn Sie mit kleinen Datenmengen arbeiten, aber wenn Sie an größeren Datensätzen arbeiten (z. B. 50.000 Datensätze), ist eine temporäre Tabelle viel schneller als eine Tabellenvariable.

Denken Sie auch daran, dass Sie sich nicht auf einen try/catch verlassen können, um eine Bereinigung innerhalb der gespeicherten Prozedur zu erzwingen. bestimmte Arten von Fehlern können nicht innerhalb eines try/catch abgefangen werden (z. B. Kompilierungsfehler aufgrund verzögerter Namensauflösung), wenn Sie wirklich sicher sein möchten, dass Sie möglicherweise eine Wrapper-gespeicherte Prozedur erstellen müssen, die ein try/catch der gespeicherten Prozedur des Arbeiters ausführen kann und mach die Aufräumarbeiten dort.

z.B. create proc Arbeiter AS BEGIN - etwas tun, hier END

create proc wrapper AS 
BEGIN 
    Create table #... 
    BEGIN TRY 
     exec worker 
     exec worker2 -- using same temp table 
     -- etc 
    END TRY 
    END CATCH 
     -- handle transaction cleanup here 
     drop table #... 
    END CATCH 
END 
Verwandte Themen