Was ist DROP IF EXISTS?
Ihr habt es in den vergangenen Monaten immer wieder gesehen und auch von der Syntax her ist die Funktionsweise von DROP IF EXISTS
relativ eindeutig einzuordnen: Löschen eines Datenbankobjekts, wenn es denn existiert. Die Syntax dazu wurde im SQL Server 2016 eingeführt und erspart uns armen Ninjas einige eher unschöne Syntax-Klimmzüge der Vergangenheit.
Wie könnt ihr mit DROP IF EXISTS arbeiten?
Die Verwendung von DROP IF EXISTS
ist denkbar einfach. Früher habt ihr Konstrukte gehabt, die über die sys
-Tabellen oder die OBJECT_ID
-Funktion geprüft haben, ob bestimmte Objekte existieren, heute verwendet ihr stattdessen DROP IF EXISTS
. Sehen wir uns das einmal an. Zunächst erzeugen wir ein Datenbank-Objekt:
CREATE TABLE #Dojo ( NinjaId int NOT NULL IDENTITY(1,1) ,NinjaName varchar(250) )
Versuchen wir nun, das Objekt nun mit einer veränderten Konfiguration noch einmal neu anzulegen:
CREATE TABLE #Dojo ( NinjaId int NOT NULL IDENTITY(1,1) ,NinjaName varchar(250) ,Age int )
Natürlich schlägt dieser Versuch fehl, da die Objektnamen in der Datenbank eindeutig sein müssen und der SQL Server meldet uns
There is already an object named '#Dojo' in the database
.
Bevor wir das Objekt anlegen müssen, müssen wir natürlich das alte Objekt löschen.
Früher hätten wir vor dem CREATE
-Statement geprüft, ob die Tabelle existiert. Ich habe das meistens gemacht, indem ich geprüft habe, ob die OBJECT_ID
-Funktion einen Wert zurückliefert:
IF OBJECT_ID('tempdb..#Dojo') IS NOT NULL DROP TABLE #Dojo; GO
Unschön an dieser Lösung war immer, dass wir für Temporäre Tabellen wie in unserem Fall “tempdb” ohne Schema (daher die zwei Punkte) abfragen mussten. Dennoch war dieser Weg natürlich zielführend, denn folgendes Statement führt dazu, dass wir eine #Dojo-Tabelle mit den gewünschten drei Spalten in der Datenbank vorfinden:
IF OBJECT_ID('tempdb..#Dojo') IS NOT NULL DROP TABLE #Dojo; GO CREATE TABLE #Dojo ( NinjaId int NOT NULL IDENTITY(1,1) ,NinjaName varchar(250) ) IF OBJECT_ID('tempdb..#Dojo') IS NOT NULL DROP TABLE #Dojo; GO CREATE TABLE #Dojo ( NinjaId int NOT NULL IDENTITY(1,1) ,NinjaName varchar(250) ,Age int )
Statt die OBJECT_ID
-Funktion zu verwenden, gab es auch die Möglichkeit, vorsorglich immer ein DROP TABLE
auszuführen und den Fehler, der auftritt, wenn das Objekt nicht existiert einfach in einem TRY CATCH
-Statement abzufangen und zu ignorieren:
BEGIN TRY DROP TABLE #Dojo2 END TRY BEGIN CATCH END CATCH GO
Auch hier lässt sich die Funktionsweise bestätigen, denn nach dem Ausführen folgendes Statements ist wieder eine #Dojo2
-Tabelle mit drei Spalten in der Datenbank:
BEGIN TRY DROP TABLE #Dojo2 END TRY BEGIN CATCH END CATCH GO CREATE TABLE #Dojo2 ( NinjaId int NOT NULL IDENTITY(1,1) ,NinjaName varchar(250) ) BEGIN TRY DROP TABLE #Dojo2 END TRY BEGIN CATCH END CATCH GO CREATE TABLE #Dojo2 ( NinjaId int NOT NULL IDENTITY(1,1) ,NinjaName varchar(250) ,Age int )
Beide Methoden funktionieren zwar nach wie vor – doch mit der neuen Syntax geht das alles viel Eleganter:
DROP TABLE IF EXISTS #Dojo3; GO
Und auch hier können wir die Funktionsfähigkeit relativ einfach demonstrieren:
DROP TABLE IF EXISTS #Dojo3; GO CREATE TABLE #Dojo3 ( NinjaId int NOT NULL IDENTITY(1,1) ,NinjaName varchar(250) ) DROP TABLE IF EXISTS #Dojo3; GO CREATE TABLE #Dojo3 ( NinjaId int NOT NULL IDENTITY(1,1) ,NinjaName varchar(250) ,Age int ) select * from #Dojo3
Natürlich gab es noch andere Wege, die Existenz von Objekten zu prüfen, indem man beispielsweise sys
-Tabellen abfragt:
SELECT name FROM tempdb.sys.objects WHERE name LIKE N'#Dojo[_]%';
Beziehungsweise:
SELECT name FROM sys.objects WHERE name = N'DojoPerm';
Doch alle diese Konstrukte sind im Endeffekt nur Hilfsmittel, die wir verwenden, um zu sagen “lösche das Objekt, wenn es existiert” und da ist es doch schön, dass der SQL Server uns mittlerweile eine Syntax an die Hand gibt, um genau das auch wirklich zu sagen.