Dodaj kolumnę do tabeli, jeśli jeszcze nie istnieje

188

Chcę napisać zapytanie do MS SQL Server, które dodaje kolumnę do tabeli. Ale nie chcę wyświetlać żadnych błędów, gdy uruchamiam / wykonuję następujące zapytanie.

Używam tego rodzaju zapytań, aby dodać tabelę ...

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

Ale nie wiem, jak napisać to zapytanie dla kolumny.

Tavousi
źródło
Powinieneś użyć sys.tableszamiast „ogólnego” sys.objects- wtedy nie musisz jawnie określać typu (to oczywiste z sys.tablesjuż ....)
marc_s
COL_LENGTH Alternative działa tylko z SQL-Server 2008, ale działa.
Paul-Henri,

Odpowiedzi:

219

Możesz użyć podobnej konstrukcji, korzystając z sys.columnstabeli io sys.objects.

IF NOT EXISTS (
  SELECT * 
  FROM   sys.columns 
  WHERE  object_id = OBJECT_ID(N'[dbo].[Person]') 
         AND name = 'ColumnName'
)
Lieven Keersmaekers
źródło
42
Zauważ, że w tym przypadku chcesz użyć JEŻELI NIE ISTNIEJE w swoim kodzie.
Nat
2
Aby zoptymalizować zapytanie, możesz użyć pierwszej 1 z instrukcją select
Banketeshvar Narayan
11
@BanketeshvarNarayan to jest nieprawidłowe. Plany wykonania dla podzapytań w EXISTSklauzuli są identyczne. Rzeczy takie jak SELECT 1lub SELECT TOP 1są niepotrzebne. Sama EXISTSklauzula mówi optymalizatorowi zapytań, aby wykonywał tylko minimalne odczyty niezbędne do oceny EXISTS... przynajmniej w SQL Server. Inne silniki DB mogą mieć mniej lub bardziej wydajny optymalizator zapytań.
Kenneth Cochran
9
@BanketeshvarNarayan Jeśli optymalizujesz swoje ADD Columnzapytania ... musisz je uruchamiać zbyt często!
Fenton
1
@ user391339 - Wysłałem konstrukcję podobną do opublikowanej przez OP, ale tak, jeśli chcesz podjąć działanie, jeśli kolumna nie istnieje, instrukcja będzie JEŚLI NIE ISTNIEJE. Naprawdę nie czuję potrzeby edytowania odpowiedzi na to pytanie, ale nie waham się edytować samodzielnie, jeśli uważasz, że to poprawa.
Lieven Keersmaekers
91
IF COL_LENGTH('table_name', 'column_name') IS NULL
BEGIN
    ALTER TABLE table_name
    ADD [column_name] INT
END
SPL
źródło
1
Próbowałem to zrobić, ale zwraca błąd informujący, że funkcja COL_LENGTH nie istnieje.
ThEpRoGrAmMiNgNoOb
3
Wymaga SQL Server 2008+
Robert Brown
6
Mały dodatek - nie należy używać nawiasów kwadratowych w nazwie kolumny, ponieważ COL_LENGTH('table_name', '[column_name]')zawsze zwraca wartość null w SQL Server 2016 ( COL_LENGTH('[table_name]', 'column_name') works as expected).
stop-cran
33

Kolejna alternatywa. Wolę takie podejście, ponieważ jest mniej pisania, ale obydwoje osiągają to samo.

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

Zauważyłem również, że twój szuka tam, gdzie istnieje stół, to oczywiście tylko to

 if COLUMNPROPERTY( OBJECT_ID('dbo.Person'),'ColumnName','ColumnId') is not null
JStead
źródło
2
Lubię to. Myślę, że najlepszą częścią publikowania tutaj jest znalezienie takich klejnotów.
JStead
2
Co to jest „ColumnId”?
Marius Stănescu,
„ColumnId” to nazwa właściwości kolumny, względem której sprawdzasz. Prawdopodobnie mogłeś użyć dowolnej nazwy właściwości istniejącej w kolumnie, takiej jak nazwa itp.
Jacques Bosch
5

Oto kolejna odmiana, która zadziałała dla mnie.

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

EDYCJA: Pamiętaj, że INFORMATION_SCHEMAwidoki nie zawsze mogą być aktualizowane, SYS.COLUMNSzamiast tego użyj :

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

Adil H. Raza
źródło
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

Mam nadzieję, że to pomoże. Więcej informacji

ShaileshDev
źródło
To działało dla mnie na SqlServer 2000, podczas gdy zaakceptowana odpowiedź nie. Widoki sys. * Wydają się być dodane gdzieś w okolicach SqlServer 2005, por. docs.microsoft.com/en-us/sql/relational-databases/…
ZeRemz
0

Sprawdzając kolumnę w innej bazie danych, możesz po prostu dołączyć nazwę bazy danych:

IF NOT EXISTS (
  SELECT * 
  FROM   DatabaseName.sys.columns 
  WHERE  object_id = OBJECT_ID(N'[DatabaseName].[dbo].[TableName]') 
         AND name = 'ColumnName'
)
Ezdrasz
źródło
-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
Najpierw kod
źródło