Fügen Sie einer Tabelle eine Spalte hinzu, falls diese noch nicht vorhanden ist

187

Ich möchte eine Abfrage für MS SQL Server schreiben, die einer Tabelle eine Spalte hinzufügt. Ich möchte jedoch keine Fehleranzeige, wenn ich die folgende Abfrage ausführe / ausführe.

Ich benutze diese Art von Abfrage, um eine Tabelle hinzuzufügen ...

IF EXISTS (
       SELECT *
       FROM   sys.objects
       WHERE  OBJECT_ID = OBJECT_ID(N'[dbo].[Person]')
              AND TYPE IN (N'U')
   )

Aber ich weiß nicht, wie ich diese Abfrage für eine Spalte schreiben soll.

Tavousi
quelle
Sie sollten sys.tablesanstelle des "generischen" verwenden sys.objects- dann müssen Sie den Typ nicht explizit angeben (es ist aus dem sys.tablesbereits ....)
ersichtlich
COL_LENGTH Alternative funktioniert nur ab SQL-Server 2008, aber es funktioniert.
Paul-Henri

Antworten:

218

Sie können ein ähnliches Konstrukt verwenden, indem Sie die sys.columnsTabelle io verwenden sys.objects.

IF NOT EXISTS (
  SELECT * 
  FROM   sys.columns 
  WHERE  object_id = OBJECT_ID(N'[dbo].[Person]') 
         AND name = 'ColumnName'
)
Lieven Keersmaekers
quelle
42
Beachten Sie, dass Sie in diesem Fall IF NOT EXISTS in Ihrem tatsächlichen Code verwenden möchten.
Nat
2
Für eine optimierte Abfrage können Sie Top 1 mit Select-Anweisung verwenden
Banketeshvar Narayan
11
@BanketeshvarNarayan das ist falsch. Die Ausführungspläne für Unterabfragen in einer EXISTSKlausel sind identisch. Dinge wie SELECT 1oder SELECT TOP 1sind unnötig. Die EXISTSKlausel selbst weist den Abfrageoptimierer an, nur die minimalen Lesevorgänge durchzuführen, die erforderlich sind, um die EXISTS... zumindest in SQL Server auszuwerten . Andere DB-Engines verfügen möglicherweise über ein mehr oder weniger effizientes Abfrageoptimierungsprogramm.
Kenneth Cochran
9
@BanketeshvarNarayan Wenn Sie Ihre ADD ColumnAbfragen optimieren ... müssen Sie sie zu oft ausführen !
Fenton
1
@ user391339 - Ich habe ein ähnliches Konstrukt wie OP veröffentlicht, aber ja, wenn Sie Maßnahmen ergreifen möchten, wenn die Spalte nicht vorhanden ist, lautet die Anweisung WENN NICHT EXISTIERT. Ich habe nicht wirklich das Bedürfnis, die Antwort darauf zu bearbeiten, aber Sie können sich gerne selbst bearbeiten, wenn Sie der Meinung sind, dass dies eine Verbesserung darstellt.
Lieven Keersmaekers
91
IF COL_LENGTH('table_name', 'column_name') IS NULL
BEGIN
    ALTER TABLE table_name
    ADD [column_name] INT
END
SPL
quelle
1
Ich habe versucht, dies zu tun, aber es wird ein Fehler zurückgegeben, der besagt, dass die Funktion COL_LENGTH nicht existiert.
ThEpRoGrAmMiNgNoOb
3
Benötigt SQL Server 2008+
Robert Brown
6
Kleiner Zusatz - man sollte keine spitzen Klammern im Spaltennamen verwenden, da COL_LENGTH('table_name', '[column_name]')in SQL Server 2016 ( COL_LENGTH('[table_name]', 'column_name') works as expected) immer null zurückgegeben wird .
Stop-Cran
33

Eine andere Alternative. Ich bevorzuge diesen Ansatz, weil er weniger schriftlich ist, aber beide das Gleiche erreichen.

IF COLUMNPROPERTY(OBJECT_ID('dbo.Person'), 'ColumnName', 'ColumnId') IS NULL
BEGIN
    ALTER TABLE Person 
    ADD ColumnName VARCHAR(MAX) NOT NULL
END

Mir ist auch aufgefallen, dass Sie nach einem Tisch suchen, der offensichtlich genau das ist

 if COLUMNPROPERTY( OBJECT_ID('dbo.Person'),'ColumnName','ColumnId') is not null
JStead
quelle
2
Ich mag das. Ich denke, das Beste am Posten hier ist, solche Edelsteine ​​zu finden.
JStead
1
Was ist 'ColumnId'?
Marius Stănescu
'ColumnId' ist der Name der Spalteneigenschaft, gegen die Sie prüfen. Sie hätten wahrscheinlich jeden Eigenschaftsnamen verwenden können, der in einer Spalte vorhanden ist, z. B. Name usw.
Jacques Bosch
5

Hier ist eine weitere Variante, die für mich funktioniert hat.

IF NOT EXISTS (SELECT 1
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE upper(TABLE_NAME) = 'TABLENAME'
        AND upper(COLUMN_NAME) = 'COLUMNNAME')
BEGIN
    ALTER TABLE [dbo].[Person] ADD Column
END
GO

BEARBEITEN: Beachten Sie, dass INFORMATION_SCHEMAAnsichten möglicherweise nicht immer aktualisiert werden. Verwenden Sie SYS.COLUMNSstattdessen:

IF NOT EXISTS (SELECT 1 FROM SYS.COLUMNS....

Adil H. Raza
quelle
0
IF NOT EXISTS (SELECT * FROM syscolumns
  WHERE ID=OBJECT_ID('[db].[Employee]') AND NAME='EmpName')
  ALTER TABLE [db].[Employee]
  ADD [EmpName] VARCHAR(10)
GO

Ich hoffe das würde helfen. Mehr Info

ShaileshDev
quelle
Dies funktionierte für mich auf SqlServer 2000, während die akzeptierte Antwort dies nicht tat. Die sys. * -Ansichten scheinen irgendwo um SqlServer 2005 hinzugefügt worden zu sein, vgl. docs.microsoft.com/en-us/sql/relational-databases/…
ZeRemz
0

Wenn Sie in einer anderen Datenbank nach einer Spalte suchen, können Sie einfach den Datenbanknamen angeben:

IF NOT EXISTS (
  SELECT * 
  FROM   DatabaseName.sys.columns 
  WHERE  object_id = OBJECT_ID(N'[DatabaseName].[dbo].[TableName]') 
         AND name = 'ColumnName'
)
Esra
quelle
-1
IF NOT EXISTS (SELECT 1  FROM SYS.COLUMNS WHERE  
OBJECT_ID = OBJECT_ID(N'[dbo].[Person]') AND name = 'DateOfBirth')
BEGIN
ALTER TABLE [dbo].[Person] ADD DateOfBirth DATETIME
END
Code zuerst
quelle