Bir SQL Server tablosunda bir sütunun olup olmadığını nasıl kontrol edebilirim?


1853

Yoksa belirli bir sütun eklemeniz gerekir. Aşağıdaki gibi bir şey var, ama her zaman yanlış döndürür:

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

Bir sütunun SQL Server veritabanının bir tablosunda olup olmadığını nasıl kontrol edebilirim?


12
Aslında sorudaki kodda yanlış bir şey olduğunu düşünmüyorum: 2008 R2'de benim için iyi çalışıyor. (Yanlış veritabanında çalıştırıyor olabilirsiniz? Belki veritabanınız büyük / küçük harfe duyarlıdır ve myTableName / myColumnName dizelerinizde doğru durumda değil misiniz? Bu tür bir sorgu COL_LENGTH çözümünden daha esnek görünüyor: Yapabiliyorum "BİLGİ_SCHEMA" ön ekini ekleyerek farklı bir veritabanında ve hatta bir veritabanı bağlantısında çalıştırmak için. Bunu COL_LENGTH meta veri işleviyle nasıl yapacağınızı göremedim.
mwardm

3
@mwardm - iyi COL_LENGTH('AdventureWorks2012.HumanResources.Department ','ModifiedDate')çalışıyor.
Martin Smith

6
Küçük ilgili ipucu: Sütun eklenmesinden sonra bir sütun sağa güncellemek istiyorsanız (ben birçok kullanıcı bu amaçla bu yazıyı aradığı inanmak) şunu kullanabilirsiniz EXEC sp_executesqlkurdu ile UPDATEaçıklamaya.
cassandrad

Asıl cevap, kontrol ettiğiniz veritabanını eklemeniz gerektiğidirFROM [YourDatabase].INFORMATION_SCHEMA.COLUMNS
Alex Kwitny

Yanıtlar:


2054

SQL Server 2005 sonrası:

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

Martin Smith'in versiyonu daha kısa:

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

Martin Smith'in versiyonunda değinilecek bir şey, columnName öğesinin köşeli parantez [] içine dahil edilmemesi. ColumnName köşeli parantez [] içindeyse, sütun tabloda mevcut olsa bile null değerini verir
Hemendra

@HemendraSinghChauhan - ismin bir parçası olmadıkları için. İçinde adı ile karşılaştırırken Ayrıca olduğunu göreceksinizsys.columns
Martin Smith

@MartinSmith bilmiyordum, cevabınızı kullanıyordum ve bununla karşılaştım. Genellikle sütunları eklerken köşeli parantez kullanıyorum, bu yüzden onları COL_LENGTH işlevinde de kullandım. Alter table Table_Name Add [ColumnName] NVarchar(max) NULL; Select COL_LENGTH('[TABLE_NAME]', '[COLUMN_NAME]')
Kodum şöyleydi

evet bu geçerli değil. COL_LENGTHTartışılması gereken argümanlar . Teorik olarak birisinin aslında bir adı olan bir sütun oluşturması mümkündür [COLUMN_NAME]- örneğin CREATE TABLE #T([[COLUMN_NAME]]] INT); SELECT * FROM #Tve bu kural olmasaydı belirsiz olurdu.
Martin Smith

987

Daha kısa bir versiyon

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

Meta verileri görüntüleme izinleriyle ilgili nokta yalnızca bu soruya değil, tüm yanıtlara uygulanır.

İlk parametre tablosu adının COL_LENGTHgerektiği gibi bir, iki veya üç parça adı biçiminde olabileceğini unutmayın .

Farklı bir veritabanındaki tabloya referans veren bir örnek

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

Bu cevapla meta veri görünümlerini kullanmaya kıyasla bir fark, meta veri işlevlerinin COL_LENGTHher zaman yalnızca yürürlükteki yalıtım düzeyinden bağımsız olarak yalnızca taahhütlü değişiklikler hakkındaki verileri döndürmesidir.


11
Bu, diğer cevaplardan daha az okunabilir, muhtemelen neden bu kadar yüksek değil.
Bill Yang

38
@Bill - Ne şekilde daha az okunabilir? Firefox'ta iyi görünüyor. Bu cevap, kabul edilen yanıttan 2 yıl sonra yayınlandı, bu da IMO derecelendirmesini açıklıyor. Bir varoluş olduğunu daha az açıklamak istiyorsan, bu tip deyimin SQL Server'da oldukça yaygın olduğunu kontrol et. örneğin IF OBJECT_ID('TableName','U') IS NULLnesne varlığını DB_ID('foo')kontrol etmek veya veritabanı varlığını kontrol etmek için kullanma.
Martin Smith

59
@MartinSmith Eminim daha az okunabilir anlamına geliyordu, çünkü bu deyimi bilmiyorsan ve bu kodu başka birinden devralmışsan, kodun ne yaptığını hemen anlamazsın. C ++ x>>2yerine bir tür yazma gibi x/4. Daha ayrıntılı kod ( if exists (select column_name from information_schema ...)) çok daha fazla yer kaplar, ancak hiç kimse ne yaptığını anlamaya çalışırken başlarını kaşımaz.
Kip

22
Daha özlü olmasının yanı sıra, bu çok daha hızlı bir çözümdür. Önbelleğe alınmış veritabanı meta verilerini kullanırken , INFORMATION_SCHEMAgörünümlere veya sys.columnsdiske isabet ederken erişim COL_LENGTH.
wqw

7
Bu muhtemelen en yüksek puan alan cevap değildir, çünkü diğerinden 2.5 yıl sonra verilmiştir. Bu yüzden iki cevaptaki derecelendirmeleri karşılaştırırken tarihleri ​​her zaman kontrol ederim. Daha önce verilen bir cevabın üstesinden gelmek çok daha uzun sürer. ;)
Sean

149

Özel gereksinimlerinize uyacak şekilde aşağıdakileri değiştirin:

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

Düzenleme ile başa çıkmak için düzenleyin Soru : Bu işe yaramalı - aptal hatalar için kodunuza dikkatlice bakın; ekinizin uygulandığı veritabanı ile aynı veritabanında BİLGİ_SCHEMA sorguluyor musunuz? Her iki ifadede de tablo / sütun adınızda bir yazım hatası var mı?


3
Ben sadece madde sonra sorunu giderir sonra TABLE_SCHEMA = 'mySchema' ekleyerek öğrendim.
Maciej

12
-1: OP'nin sorusuna cevap vermez, OP'nin bunu sormamasına rağmen yeni bir sütun nasıl ekleneceğine dair yeni bilgileri ekler, OP'nin yorumunu ele almaz.
ANeves

1
+1 OP'nin sorusunu, OP'nin zaten bir sonraki adımda ekleyeceği ek bilgiler bonusuyla mükemmel bir şekilde cevaplar. Aradığım da buydu.
Bitterblue

74

Bunu dene...

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
Bu yöntem SQL CE ile de çalışır, ancak bahsedilen diğer yöntemlerin bazıları işe yaramaz.
SWalters - Monica'yı eski durumuna döndür

9
;) SELECT 1Yerine kullanabilirsiniz SELECT TOP 1 1.
shA.t

4
Bir EXISTSifade içinde SQL, sütunları otomatik olarak optimize eder (çok benzer count(*)), bu yüzden SELECT *yeterli olacaktır.
Marc L.

Tamlık uğruna and [TABLE_SCHEMA] = '???'WHERE yantümcesine eklemeyi düşünmelisiniz .
Andrew Jens

50

Sütun varlığını kontrol eden insanlar için onu bırakmak.

Gönderen SQL Server 2016 Yeni DİE ifadeleri yerine büyük kullanabilirsiniz IFsarmalayıcılarını

ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name

47

INFORMATION_SCHEMA.COLUMNSMicrosoft, sistem tablolarını sürümler arasında korumayı garanti etmediği için bir sistem tablosunu tercih ederim . Örneğin, dbo.syscolumnsSQL 2008'de hala çalışır, ancak kullanımdan kaldırılmıştır ve gelecekte herhangi bir zamanda kaldırılabilir.



5
Evet, INFORMATION_SCHEMAgörünümler yalnızca ANSI standardında meta veriler içerdiğinden , bu söylemeye gerek yok . Ancak bu bir varlık testi için yeterlidir.
Christian Hayter

3
Microsoft, "SQL Server'ın gelecekteki sürümlerinde, Microsoft, sütun listesinin sonuna sütun ekleyerek herhangi bir sistem kataloğu görünümünün tanımını artırabilir. Üretim kodunda SELECT * FROM sys.catalog_view_name sözdizimini kullanmamanızı öneririz. döndürülen sütunlar uygulamanızı değiştirebilir ve bozabilir. " Bu, sütunları kaldırmayacaklarını veya sıralarını değiştirmeyeceklerini gösterir. Bu, kenar durumları dışındaki tüm durumlar için yeterince iyi uyumluluktur.
siride

42

İlgilendiğiniz tablolar hakkında hemen hemen her şeyi öğrenmek için bilgi şeması sistemi görünümlerini kullanabilirsiniz:

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

Bilgi_semalarını kullanarak görünümleri, saklı yordamları ve veritabanı hakkında hemen hemen her şeyi sorgulayabilirsiniz.


Anketin kullandığı tam olarak bu, mevcut değilse sütunu nasıl ekleyeceğini bilmesi gerekiyordu.
Birel

35

Şuna benzer bir şey deneyin:

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

Sonra şu şekilde kullanın:

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

Hem SQL Server 2000 hem de SQL Server 2005 üzerinde çalışmalıdır. SQL Server 2008 hakkında emin değilim, ama neden görmüyorum.


34

Öncelikle ( alan tanımlarını içeren dahili bir SQL Server tablosu ) table/ column( id/ name) kombinasyonunun mevcut dbo.syscolumnsolup olmadığını ALTER TABLEve eklemek için uygun sorguyu yayınlamıyorsanız kontrol edin . Örneğin:

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

28

İyi bir arkadaşım ve meslektaşım, bir sütunu kontrol etmek için IFSQL işlevlerine OBJECT_IDve COLUMNPROPERTYSQL SERVER 2005+ uygulamasında nasıl bir blok kullanabileceğinizi gösterdi . Aşağıdakine benzer bir şey kullanabilirsiniz:

Burada kendiniz görebilirsiniz

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
Tabii ki, tablonun var olduğundan eminseniz, durumun ilk kısmını dışarıda bırakabilir ve COLUMNPROPERTYsadece kontrol edebilirsiniz .
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

Bu benim için SQL 2000'de çalıştı:

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

21

Bunu dene

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') 

İhtiyacınız yoktur INFORMATION_SCHEMA.TABLESve belirli bir tablo için sütunları filtrelemezsiniz, bu nedenle bazen ayrı tablolarda aynı sütun adları için birden fazla satır döndürür;).
shA.t

19

SQL SERVER 2000 için benzer bir şeye ihtiyacım vardı ve @Mitch'in işaret ettiği gibi, bu sadece 2005+ sürümünde çalışıyor.

Başka birine yardım ederse, sonunda benim için işe yarayan şey buydu:

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
Sanırım table_schema = 'şema_adı' demek istediniz.
Tab Alleman

11

Kabul edilen cevabın geçici tablo versiyonu :

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

1
Bunun kabul edilen cevaptan farkı nedir? Geçici tablo kabul edilen cevapta işe yaramaz mı?
John Saunders

1
Doğru. 'Sys.columns', 'tempdb.sys.columns' olarak belirtilmesi ve tablo adı 'tempdb ..' ile önceden gelmesi gerektiğinden, kabul edilen yanıt geçici tablolar için çalışmaz.
crokusek

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

8

Buğdayın cevabı iyidir, ancak herhangi bir şema veya veritabanında aynı tablo adı / sütun adı çiftinin bulunmadığını varsayar. Bu durum için güvenli hale getirmek için bunu kullanın ...

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

8

Bir sütunun varlığını kontrol etmenin birkaç yolu vardır. INFORMATION_SCHEMA.COLUMNSKullanıcı ile iletişim kurmak için yaratıldığı gibi kullanmanızı şiddetle tavsiye ederim . Aşağıdaki tabloları düşünün:

 sys.objects
 sys.columns

ve hatta kontrol etmek için başka erişim yöntemleri de system catalog.

Ayrıca, kullanmaya gerek yok SELECT *, sadece test edinNULL value

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

1
Ne olursa olsun, hatta eğer SELECT *birlikte EXISTSkullanıldığında Varlığından zaman gerçekten varlığı için tüm satırları ve tüm sütunları, içten sadece çek seçin ve tüm satır ve sütunlar için değil aslında denetler nedeniyle,
Pawan Nogariya

7

En basit ve anlaşılır çözümlerden biri:

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

İşte veritabanına sütun eklemeyi yönetmek için kullandığım basit bir komut dosyası:

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

Bu örnekte, Namebir ColumnNameilave edilecek ve Object_IdbirTableName


4

Aşağıdaki sorgu, aranan sütunun tabloda olup olmadığını kontrol etmek için kullanılabilir. Aşağıda gösterilen arama sonuçlarına göre karar alabiliriz.

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

Yine başka bir varyasyon ...

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

1

table -> script table as -> yeni pencereler - tasarım scriptiniz var. yeni pencerelerde sütun adını kontrol et ve bul


1

Sütunun verilen tabloda olup olmadığını kontrol etmek için aşağıdaki sorguyu yürütün:

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

Başka bir katkı, mevcut değilse sütunu ekleyen aşağıdaki örnektir.

    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

Umarım yardımcı olur. Simone


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

Bu, bu sorunun oldukça kolay yolu ve doğrudan çözümü olmalıdır. Bunu benzer senaryolar için birçok kez kullandım. Bir cazibe gibi çalışır, şüphe yok.


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

Sütun yoksa bir şey yapın:

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

Sütun varsa bir şey yapın:

BEGIN
    IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NOT NULL)
    BEGIN
        //Do something
    END
END;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.