Sollte ich prüfen, ob temporäre Tabellen in gespeicherten Prozeduren vorhanden sind?

7

Gibt es einen Randfall, in dem empfohlen wird, zu Beginn einer gespeicherten Prozedur explizit nach temporären Tabellen zu suchen, diese zu löschen und zu erstellen, anstatt sie nur zu erstellen?

Gibt es auch einen Fall, in dem das explizite Löschen am Ende der gespeicherten Prozedur dem Bereinigen durch SQL Server vorzuziehen ist?

Akash
quelle

Antworten:

7

Beim Überprüfen auf #tbl

Es kann nicht schaden, zu Beginn des Vorgangs die Existenz der Tabelle zu überprüfen (und sie zu löschen, falls vorhanden), aber es hängt davon ab, wie Sie mit diesem Szenario umgehen möchten, und in den meisten Fällen ist es nicht möglich, dass sie bereits vorhanden ist jedenfalls (zumindest wenn es sich um dieselbe # temp-Tabelle handelt, die in dieser gespeicherten Prozedur definiert ist).

Sie überprüfen die Existenz einer Tabelle mit:

IF OBJECT_ID('tempdb..#tablename') IS NOT NULL

Sie können tempdb.sys.tables nicht überprüfen, da der tatsächliche Name lautet #tablename__________some hex code, und Sie sollten ihn OBJECT_ID('...') > 0 aufgrund dieses potenziellen Problems nicht verwenden .

Natürlich gibt es Ausnahmen. Zwei, die mir in den Sinn kommen:

  • Wenn Sie alles #tempoder #toder aufrufen #x, ist es möglich, dass eine solche Tabelle bereits in einem äußeren Bereich vorhanden ist, bevor Sie die Prozedur aufrufen. Sie könnten einen Fall machen, dass Sie ihn einfach fallen lassen und in diesem Fall Ihren neuen erstellen sollten, aber Sie könnten auch den Fall machen, dass dies eine Fehlerbedingung ist, über die Sie wissen möchten - also ist es vielleicht in Ordnung, dass dies CREATE TABLE #xfehlschlägt.

  • Möglicherweise möchten Sie tatsächlich eine # temp-Tabelle verwenden, die in einem äußeren Bereich erstellt wurde, und nur eine erstellen, wenn sie in diesem äußeren Bereich nicht definiert wurde. Dies ist möglich und ich verwende diese Technik ständig, aber normalerweise nur, wenn ich Daten aus Systemprozeduren erfassen möchte, die ich selbst nicht einfach manipulieren kann (z sp_helptext. B. ). Also könnte ich das tun:

    CREATE TABLE #x([Text] NVARCHAR(MAX));
    GO
    CREATE PROCEDURE dbo.myhelp @p SYSNAME
    AS
      INSERT #x EXEC sp_helptext @p;
    GO
    EXEC dbo.myhelp N'dbo.myhelp'; -- inception
    GO
    SELECT [Text] FROM #x;
    

    Dies funktioniert, obwohl #xes außerhalb definiert ist. Das ist ein schreckliches Beispiel, weil ich es lieber verwenden würde sys.sql_modules, aber ich bin sicher, Sie verstehen den Punkt und können sich vorstellen, wie Sie das mit Ihren eigenen Verfahren tun könnten.

On DROP TABLE #tbl;

Ich denke, ob Sie #temp-Tabellen am Ende des Verfahrens explizit löschen sollten, steht sehr zur Debatte und würde daher als primär meinungsbasiert geschlossen werden. Sehen Sie sich diese hervorragenden Blog-Beiträge von Paul White an , lesen Sie sie gründlich durch und formulieren Sie eine bestimmte Frage, wenn nicht alle Ihre Fragen beantwortet wurden:

Aaron Bertrand
quelle
2

Ich denke, es würde davon abhängen, wie Sie temporäre Tabellen verwenden. Wenn verwendet SELECT INTOwird, würde ich vorher testen und dropes am Ende. Das Testen vor der Hand und das Fallenlassen verhindern unerwünschte Probleme auf der Straße, die auftreten können oder nicht. Für mich ist dies nur eine gute Code-Praxis.

Wenn Sie CREATE TABLEzuerst die temporäre Tabelle erstellen, würde ich wahrscheinlich aus Gewohnheit dasselbe tun und versuchen, einen Standard für die Entwicklung von Prozeduren beizubehalten. Damit könnten Sie wahrscheinlich auskommen, wenn Sie nur die drop-Anweisung am Ende des Vorgangs haben und Code mit nur drop am Ende gesehen haben.

Wenn Sie in einem Team sind oder nur Sie selbst, überlegen Sie sich einen Standard und halten Sie sich daran.


quelle