Aggiungi una colonna a una tabella, se non esiste già


188

Voglio scrivere una query per MS SQL Server che aggiunge una colonna in una tabella. Ma non voglio visualizzare alcun errore quando eseguo / eseguo la seguente query.

Sto usando questo tipo di query per aggiungere una tabella ...

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

Ma non so come scrivere questa query per una colonna.



Si dovrebbe usare al sys.tablesposto del "generico" sys.objects- quindi non è necessario specificare esplicitamente il tipo (è ovvio dal sys.tablesgià ....)
marc_s

COL_LENGTH L'alternativa funziona solo da SQL Server 2008, ma funziona.
Paul-Henri,

Risposte:


219

Puoi usare un costrutto simile usando la sys.columnstabella io sys.objects.

IF NOT EXISTS (
  SELECT * 
  FROM   sys.columns 
  WHERE  object_id = OBJECT_ID(N'[dbo].[Person]') 
         AND name = 'ColumnName'
)

42
Si noti che in questo caso si desidera utilizzare SE NON ESISTE nel proprio codice.
Nat

2
Per una query ottimizzata è possibile utilizzare la top 1 con l'istruzione select
Banketeshvar Narayan

11
@BanketeshvarNarayan questo non è corretto. I piani di esecuzione per le sottoquery in una EXISTSclausola sono identici. Cose come SELECT 1o SELECT TOP 1non sono necessarie. La EXISTSclausola stessa dice a Query Optimizer di eseguire solo le letture minime necessarie per valutare EXISTS... almeno in SQL Server. Altri motori DB possono avere un Query Optimizer più o meno efficiente.
Kenneth Cochran,

9
@BanketeshvarNarayan Se stai ottimizzando le tue ADD Columnquery ... devi eseguirle troppo spesso!
Fenton,

1
@ user391339 - Ho pubblicato un costrutto simile a quello pubblicato da OP, ma sì, se si desidera agire se la colonna non esiste, la dichiarazione sarebbe SE NON ESISTE. Non sento davvero il bisogno di modificare la risposta per questo, ma mi sento libero di modificare te stesso se pensi che sia un miglioramento.
Lieven Keersmaekers,

91
IF COL_LENGTH('table_name', 'column_name') IS NULL
BEGIN
    ALTER TABLE table_name
    ADD [column_name] INT
END

1
Ho provato a farlo ma restituisce un errore che indica che la funzione COL_LENGTH non esiste.
ThEpRoGrAmMiNgNoOb

3
Richiede SQL Server 2008+
Robert Brown il

6
Piccola aggiunta: non si dovrebbero usare parentesi quadre nel nome della colonna, poiché COL_LENGTH('table_name', '[column_name]')restituire sempre null in SQL Server 2016 ( COL_LENGTH('[table_name]', 'column_name') works as expected).
stop-cran,

33

Un'altra alternativa Preferisco questo approccio perché è meno scritto ma i due ottengono la stessa cosa.

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

Ho anche notato che il tuo sta cercando dove esiste un tavolo che è ovviamente solo questo

 if COLUMNPROPERTY( OBJECT_ID('dbo.Person'),'ColumnName','ColumnId') is not null

2
Mi piace. Penso che la parte migliore di pubblicare qui sia trovare gemme come questa.
JStead

2
Che cos'è "ColumnId"?
Marius Stănescu il

'ColumnId' è il nome della proprietà della colonna che si sta verificando. Probabilmente avresti potuto usare qualsiasi nome di proprietà esistente su una colonna, come nome, ecc.
Jacques Bosch,

5

Ecco un'altra variante che ha funzionato per me.

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

EDIT: Nota che le INFORMATION_SCHEMAvisualizzazioni potrebbero non essere sempre aggiornate, utilizzare SYS.COLUMNSinvece:

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



0

Quando controlli una colonna in un altro database, puoi semplicemente includere il nome del database:

IF NOT EXISTS (
  SELECT * 
  FROM   DatabaseName.sys.columns 
  WHERE  object_id = OBJECT_ID(N'[DatabaseName].[dbo].[TableName]') 
         AND name = 'ColumnName'
)

-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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.