Come verificare se esiste una colonna in una tabella di SQL Server?


1853

Devo aggiungere una colonna specifica se non esiste. Ho qualcosa di simile al seguente, ma restituisce sempre false:

IF EXISTS(SELECT *
          FROM   INFORMATION_SCHEMA.COLUMNS
          WHERE  TABLE_NAME = 'myTableName'
                 AND COLUMN_NAME = 'myColumnName') 

Come posso verificare se esiste una colonna in una tabella del database di SQL Server?


12
In realtà non penso che ci sia qualcosa di sbagliato nel codice nella domanda: funziona perfettamente per me nel 2008 R2. (Forse lo stavi eseguendo nel database sbagliato? Forse il tuo database faceva distinzione tra maiuscole e minuscole e non avevi il caso giusto nelle tue stringhe myTableName / myColumnName? Questo tipo di query sembra più flessibile della soluzione COL_LENGTH: sono in grado per eseguirlo su un altro database e persino su un collegamento al database prefissando opportunamente "INFORMATION_SCHEMA". Impossibile vedere come farlo con la funzione metadata COL_LENGTH.
mwardm,

3
@mwardm - COL_LENGTH('AdventureWorks2012.HumanResources.Department ','ModifiedDate')funziona benissimo.
Martin Smith,

6
Piccolo suggerimento correlato: se si desidera aggiornare una colonna subito dopo l'aggiunta della colonna (credo che molti utenti stessero cercando questo articolo a tale scopo), è possibile utilizzare EXEC sp_executesqlcon l' UPDATEistruzione formata .
cassandrad,

La vera risposta è che dovresti aggiungere il database che stai controllando, quindi èFROM [YourDatabase].INFORMATION_SCHEMA.COLUMNS
Alex Kwitny,

Risposte:


2054

SQL Server 2005 in poi:

IF EXISTS(SELECT 1 FROM sys.columns 
          WHERE Name = N'columnName'
          AND Object_ID = Object_ID(N'schemaName.tableName'))
BEGIN
    -- Column Exists
END

La versione di Martin Smith è più breve:

IF COL_LENGTH('schemaName.tableName', 'columnName') IS NOT NULL
BEGIN
    -- Column Exists
END

Nella versione di Martin Smith, una cosa da menzionare è di non includere columnName tra parentesi quadre []. Quando columnName è racchiuso tra parentesi quadre [], verrà restituito null anche se la colonna esiste nella tabella
Hemendra

@HemendraSinghChauhan - questo perché non fanno parte del nome. Scoprirai anche che quando si confronta con il nome insys.columns
Martin Smith

@MartinSmith non lo sapeva, stavo usando la tua risposta e mi sono imbattuto in questo. In genere utilizzo parentesi quadre durante l'aggiunta di colonne, quindi le ho usate anche all'interno della funzione COL_LENGTH. Il mio codice era così:Alter table Table_Name Add [ColumnName] NVarchar(max) NULL; Select COL_LENGTH('[TABLE_NAME]', '[COLUMN_NAME]')
Hemendra il

sì, questo non è valido. Gli argomenti COL_LENGTHdevono essere non quotati. È teoricamente possibile per qualcuno creare una colonna che in realtà ha un nome di [COLUMN_NAME]- ad esempio CREATE TABLE #T([[COLUMN_NAME]]] INT); SELECT * FROM #Te quindi sarebbe ambiguo se questa non fosse la regola.
Martin Smith,

987

Una versione più concisa

IF COL_LENGTH('table_name','column_name') IS NULL
BEGIN
/* Column does not exist or caller does not have permission to view the object */
END

Il punto sulle autorizzazioni per la visualizzazione dei metadati si applica a tutte le risposte, non solo a questa.

Si noti che il primo nome della tabella dei parametri COL_LENGTHpuò essere in uno, due o tre formati di nome della parte come richiesto.

Un esempio che fa riferimento a una tabella in un database diverso è

COL_LENGTH('AdventureWorks2012.HumanResources.Department','ModifiedDate')

Una differenza con questa risposta rispetto all'utilizzo delle viste dei metadati è che le funzioni dei metadati come COL_LENGTHsempre restituiscono solo dati sulle modifiche impegnate indipendentemente dal livello di isolamento in vigore.


11
Questo è meno leggibile di alcune delle altre risposte, probabilmente perché non è così apprezzato.
Bill Yang,

38
@Bill - Meno leggibile in che modo? Sembra a posto in Firefox. Questa risposta è stata pubblicata più di 2 anni dopo quella accettata, il che spiega il rating IMO. Se intendevi dire meno chiaramente che si tratta di un'esistenza, questo tipo di linguaggio è abbastanza comune in SQL Server. ad es. usare IF OBJECT_ID('TableName','U') IS NULLper controllare l'esistenza dell'oggetto o DB_ID('foo')per controllare l'esistenza del database.
Martin Smith,

59
@MartinSmith Sono sicuro che intendesse meno leggibile perché se non conoscessi questo idioma e ereditassi questo codice da qualcun altro, non capiresti immediatamente cosa fa il codice. Un po 'come scrivere x>>2invece che x/4in C ++. Il codice più dettagliato ( if exists (select column_name from information_schema ...)) occupa molto più spazio, ma nessuno si griderebbe mai la testa cercando di capire cosa fa.
Kip

22
Oltre a più conciso, questa è una soluzione molto più veloce. Accesso a INFORMATION_SCHEMAvisualizzazioni o sys.columnshit del disco, mentre COL_LENGTHutilizza metadati del database memorizzati nella cache.
settimana

7
Questa probabilmente non è la risposta più votata perché è stata data 2,5 anni dopo l'altra. Ecco perché controllo sempre le date confrontando le valutazioni su due risposte. Ci vuole molto più tempo per superare una risposta che è stata data molto prima. ;)
Sean,

149

Modifica quanto segue per soddisfare le tue esigenze specifiche:

if not exists (select
                     column_name
               from
                     INFORMATION_SCHEMA.columns
               where
                     table_name = 'MyTable'
                     and column_name = 'MyColumn')
    alter table MyTable add MyColumn int

Modifica per gestire la modifica in questione : dovrebbe funzionare: osserva attentamente il codice per individuare errori stupidi; stai richiedendo ad esempio INFORMATION_SCHEMA sullo stesso database a cui viene applicato l'inserimento? Hai un refuso nel nome della tabella / colonna in entrambe le istruzioni?


3
Ho appena scoperto che l'aggiunta di TABLE_SCHEMA = 'mySchema' dopo la quale la clausola risolve il problema.
Maciej,

12
-1: non risponde alla domanda di OP, aggiunge solo le nuove informazioni su come aggiungere una nuova colonna nonostante OP non lo chieda affatto, non risponde al commento di OP.
ANeves

1
+1 Risponde perfettamente alla domanda dell'OP con un bonus delle informazioni aggiuntive che l'OP stava cercando per il prossimo. E questo era quello che stavo cercando.
Bitterblue,

74

Prova questo...

IF NOT EXISTS(
  SELECT TOP 1 1
  FROM INFORMATION_SCHEMA.COLUMNS
  WHERE 
    [TABLE_NAME] = 'Employees'
    AND [COLUMN_NAME] = 'EmployeeID')
BEGIN
  ALTER TABLE [Employees]
    ADD [EmployeeID] INT NULL
END

6
Questo metodo funziona anche con SQL CE, mentre alcuni degli altri metodi menzionati non lo fanno.
SWalters - Ripristina Monica il

9
Puoi usare al SELECT 1posto di SELECT TOP 1 1;).
shA.t

4
All'interno di EXISTSun'istruzione SQL ottimizza automaticamente le colonne (molto simili count(*)), quindi SELECT *sarà sufficiente.
Marc L.

Per completezza, dovresti considerare di aggiungere and [TABLE_SCHEMA] = '???'alla clausola WHERE.
Andrew Jens,

51

Per le persone che stanno controllando l'esistenza della colonna per lasciarla cadere.

Da SQL Server 2016 è possibile utilizzare le nuove istruzioni DIE anziché i IFwrapper di grandi dimensioni

ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name

47

Preferirei INFORMATION_SCHEMA.COLUMNSuna tabella di sistema perché Microsoft non garantisce la conservazione delle tabelle di sistema tra le versioni. Ad esempio, dbo.syscolumnsfunziona ancora in SQL 2008, ma è obsoleto e potrebbe essere rimosso in qualsiasi momento in futuro.



5
Bene sì, questo è ovvio poiché le INFORMATION_SCHEMAviste contengono solo metadati standard ANSI. Tuttavia, questo è sufficiente per un test di esistenza.
Christian Hayter,

3
Microsoft dice "Nelle versioni future di SQL Server, Microsoft potrebbe aumentare la definizione di qualsiasi vista del catalogo di sistema aggiungendo colonne alla fine dell'elenco di colonne. Si sconsiglia di utilizzare la sintassi SELECT * FROM sys.catalog_view_name nel codice di produzione perché il numero di le colonne restituite potrebbero cambiare e interrompere l'applicazione. " Ciò implica che non rimuoveranno le colonne o cambieranno il loro ordine. È una compatibilità all'indietro abbastanza buona per tutti i casi, tranne Edge.
siride,

42

Puoi utilizzare le viste di sistema dello schema di informazioni per scoprire praticamente qualsiasi cosa sulle tabelle che ti interessano:

SELECT *
  FROM INFORMATION_SCHEMA.COLUMNS
 WHERE TABLE_NAME = 'yourTableName'
 ORDER BY ORDINAL_POSITION

Puoi anche interrogare viste, procedure memorizzate e praticamente qualsiasi cosa sul database usando le viste Information_schema.


Questo è esattamente ciò che utilizza il questionario, aveva bisogno di sapere come aggiungere la colonna se non esistesse.
Birel

35

Prova qualcosa del tipo:

CREATE FUNCTION ColumnExists(@TableName varchar(100), @ColumnName varchar(100))
RETURNS varchar(1) AS
BEGIN
DECLARE @Result varchar(1);
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = @TableName AND COLUMN_NAME = @ColumnName)
BEGIN
    SET @Result = 'T'
END
ELSE
BEGIN
    SET @Result = 'F'
END
RETURN @Result;
END
GO

GRANT EXECUTE ON  [ColumnExists] TO [whoever]
GO

Quindi usalo in questo modo:

IF ColumnExists('xxx', 'yyyy') = 'F'
BEGIN
  ALTER TABLE xxx
  ADD yyyyy varChar(10) NOT NULL
END
GO

Dovrebbe funzionare sia su SQL Server 2000 che su SQL Server 2005. Non sei sicuro di SQL Server 2008, ma non vedi perché no.


34

Verificare innanzitutto se la combinazione table/ column( id/ name) esiste in dbo.syscolumns(una tabella interna di SQL Server che contiene le definizioni dei campi) e, in caso contrario, emettere la ALTER TABLEquery appropriata per aggiungerla. Per esempio:

IF NOT EXISTS ( SELECT  *
            FROM    syscolumns
            WHERE   id = OBJECT_ID('Client')
                    AND name = 'Name' ) 
ALTER TABLE Client
ADD Name VARCHAR(64) NULL

28

Un mio caro amico e collega mi ha mostrato come è possibile utilizzare anche un IFblocco con funzioni SQL OBJECT_IDe COLUMNPROPERTYin SQL SERVER 2005+ per verificare la presenza di una colonna. Puoi usare qualcosa di simile al seguente:

Puoi vedere di persona qui

IF (OBJECT_ID(N'[dbo].[myTable]') IS NOT NULL AND
    COLUMNPROPERTY( OBJECT_ID(N'[dbo].[myTable]'), 'ThisColumnDoesNotExist', 'ColumnId') IS NULL)
BEGIN
    SELECT 'Column does not exist -- You can add TSQL to add the column here'
END

1
E, naturalmente, se sei sicuro che la tabella esista, puoi tralasciare la prima parte della condizione e controllare COLUMNPROPERTYsolo.
Ruud Helderman,

26
declare @myColumn   as nvarchar(128)
set @myColumn = 'myColumn'
if not exists (
    select  1
    from    information_schema.columns columns 
    where   columns.table_catalog   = 'myDatabase'
        and columns.table_schema    = 'mySchema' 
        and columns.table_name      = 'myTable' 
        and columns.column_name     = @myColumn
    )
begin
    exec('alter table myDatabase.mySchema.myTable add'
    +'    ['+@myColumn+'] bigint       null')
end

22

Questo ha funzionato per me in SQL 2000:

IF EXISTS 
(
    SELECT * 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE table_name = 'table_name' 
    AND column_name = 'column_name'
)
BEGIN
...
END

21

Prova questo

SELECT COLUMNS.*
FROM   INFORMATION_SCHEMA.COLUMNS COLUMNS,
       INFORMATION_SCHEMA.TABLES TABLES
WHERE  COLUMNS.TABLE_NAME = TABLES.TABLE_NAME
       AND Upper(COLUMNS.COLUMN_NAME) = Upper('column_name') 

Non è necessario INFORMATION_SCHEMA.TABLESe non si filtrano le colonne per una tabella specifica, quindi a volte restituisce più di una riga per gli stessi nomi di colonna in tabelle separate;).
shA.t

19

Avevo bisogno di simili per SQL SERVER 2000 e, come sottolinea @Mitch, questo funziona solo nel 2005+.

Dovrebbe aiutare qualcun altro, questo è ciò che ha funzionato per me alla fine:

if exists (
    select * 
    from 
        sysobjects, syscolumns 
    where 
        sysobjects.id = syscolumns.id 
        and sysobjects.name = 'table' 
        and syscolumns.name = 'column')

15
if exists (
  select * 
  from INFORMATION_SCHEMA.COLUMNS 
  where TABLE_NAME = '<table_name>' 
  and COLUMN_NAME = '<column_name>'
) begin
  print 'Column you have specified exists'
end else begin
  print 'Column does not exist'
end

13
IF NOT EXISTS( SELECT NULL
            FROM INFORMATION_SCHEMA.COLUMNS
           WHERE table_name = 'TableName'
             AND table_schema = 'SchemaName'
             AND column_name = 'ColumnName')  BEGIN

  ALTER TABLE [SchemaName].[TableName] ADD [ColumnName] int(1) NOT NULL default '0';

END;

2
Penso che intendevi table_schema = 'nome_schema'.
Tab Alleman,

11

Una versione della tabella temporanea della risposta accettata :

if (exists(select 1 
             from tempdb.sys.columns  
            where Name = 'columnName'
              and Object_ID = object_id('tempdb..#tableName')))
begin
...
end

1
In che modo si differenzia dalla risposta accettata? Una tabella temporanea non funzionerebbe nella risposta accettata?
John Saunders,

1
Corretta. La risposta accettata non funziona per le tabelle temporanee perché "sys.columns" deve essere specificato come "tempdb.sys.columns" e il nome della tabella deve essere preceduto da "tempdb ..".
crokusek,

10
select distinct object_name(sc.id)
from syscolumns sc,sysobjects so  
where sc.name like '%col_name%' and so.type='U'

8

La risposta di Wheat è buona, ma presuppone che non ci siano coppie identiche di nome tabella / colonna in qualsiasi schema o database. Per renderlo sicuro per quella condizione usa questo ...

select *
from Information_Schema.Columns
where Table_Catalog = 'DatabaseName'
  and Table_Schema = 'SchemaName'
  and Table_Name = 'TableName'
  and Column_Name = 'ColumnName'

8

Esistono diversi modi per verificare l'esistenza di una colonna. Consiglio vivamente di utilizzare INFORMATION_SCHEMA.COLUMNScome è stato creato al fine di comunicare con l'utente. Prendi in considerazione le seguenti tabelle:

 sys.objects
 sys.columns

e anche alcuni altri metodi di accesso disponibili per il controllo system catalog.

Inoltre, non è necessario utilizzarlo SELECT *, è sufficiente testarloNULL value

IF EXISTS(
           SELECT NULL 
           FROM INFORMATION_SCHEMA.COLUMNS
           WHERE
             TABLE_NAME = 'myTableName'
             AND COLUMN_NAME = 'myColumnName'
         ) 

1
Non importa, anche se SELECT *con EXISTS, perché quando esiste è usato in realtà non selezionare tutte le righe e tutte le colonne, internamente solo verifica l'esistenza e in realtà non verifica la presenza di tutte le righe e le colonne
Pawan Nogariya

7

Una delle soluzioni più semplici e comprensibili è:

IF COL_LENGTH('Table_Name','Column_Name') IS NULL
 BEGIN
    -- Column Not Exists, implement your logic
 END 
ELSE
 BEGIN
    -- Column Exists, implement your logic
 END

7

Ecco un semplice script che uso per gestire l'aggiunta di colonne nel database:

IF NOT EXISTS (
        SELECT *
        FROM sys.Columns
        WHERE Name = N'QbId'
            AND Object_Id = Object_Id(N'Driver')
        )
BEGIN
    ALTER TABLE Driver ADD QbId NVARCHAR(20) NULL
END
ELSE
BEGIN
    PRINT 'QbId is already added on Driver'
END

In questo esempio, Nameè il ColumnNameda aggiungere ed Object_Idè ilTableName


4

La query di seguito può essere utilizzata per verificare se esiste una colonna cercata nella tabella. Possiamo prendere una decisione in base al risultato cercato anche come mostrato di seguito.

IF EXISTS (SELECT 'Y' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = <YourTableName> AND COLUMN_NAME = <YourColumnName>)
  BEGIN
    SELECT 'Column Already Exists.'
  END
  ELSE
  BEGIN
    ALTER TABLE <YourTableName> ADD <YourColumnName> <DataType>[Size]
  END

3

Ancora un'altra variante ...

SELECT 
  Count(*) AS existFlag 
FROM 
  sys.columns 
WHERE 
  [name] = N 'ColumnName' 
  AND [object_id] = OBJECT_ID(N 'TableName')

1

tabella -> tabella degli script come -> nuove finestre - si dispone di uno script di progettazione. controlla e trova il nome della colonna in nuove finestre


1

Eseguire la query seguente per verificare se la colonna esiste nella tabella indicata:

IF(SELECT COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'TableName' AND COLUMN_NAME = 'ColumnName') IS NOT NULL
PRINT 'Column Exists in the given table';

1

Un altro contributo è il seguente esempio che aggiunge la colonna se non esiste.

    USE [Northwind]
    GO

    IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS 
                    WHERE TABLE_NAME = 'Categories'
                        AND COLUMN_NAME = 'Note')
    BEGIN

    ALTER TABLE Categories ADD Note NVARCHAR(800) NULL

    END
    GO

Spero che sia d'aiuto. Simone


0
IF EXISTS(SELECT 1 FROM sys.columns 
      WHERE Name = N'columnName'
      AND Object_ID = Object_ID(N'schemaName.tableName'))

Questo dovrebbe essere il modo più semplice e la soluzione diretta a questo problema. L'ho usato più volte per scenari simili. Funziona come un fascino, non ci sono dubbi.


0
IF EXISTS (
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_CATALOG = 'Database Name'
and TABLE_SCHEMA = 'Schema Name'
and TABLE_NAME = 'Table Name'
and COLUMN_NAME = 'Column Name'
and DATA_TYPE = 'Column Type') -- Where statement lines can be deleted.

BEGIN
--COLUMN EXISTS IN TABLE
END

ELSE BEGIN
--COLUMN DOES NOT EXISTS IN TABLE
END

0

Fai qualcosa se la colonna non esiste:

BEGIN
    IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NULL)
    BEGIN
        //Do something
    END
END;

Fai qualcosa se esiste una colonna:

BEGIN
    IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NOT NULL)
    BEGIN
        //Do something
    END
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.