Soru Bir SQL Server tablosunda bir sütun olup olmadığını nasıl kontrol edilir?


Varsa belirli bir sütun eklemem 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') 

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


1575
2017-09-25 12:34


Menşei


Aslında bu sorudaki bir kodun yanlış bir şey olduğunu düşünmüyorum: 2008'de bana göre iyi çalışmalar yapıyor R2. (Belki de bunu yanlış veritabanında çalıştırıyordunuz? Belki veritabanınız büyük / küçük harfe duyarlıdır ve myTableName / myColumnName dizelerinizde doğru bir durum bulamadınız mı? Bu tür bir sorgu COL_LENGTH çözümüne göre daha esnek görünüyor: "INFORMATION_SCHEMA" önekini yaparak farklı bir veritabanına ve hatta bir veritabanı bağlantısına karşı çalıştırmak için .COL_LENGTH meta veri işleviyle bunun nasıl yapılacağını göremedik. - mwardm
@mwardm - COL_LENGTH('AdventureWorks2012.HumanResources.Department ','ModifiedDate') iyi çalışıyor. - Martin Smith
Küçük ilgili ipucu: sütun ekleme işleminden hemen sonra bir sütunu güncellemek istiyorsanız (birçok kullanıcının bu makaleyi bu amaçla aradığını düşünüyorum) EXEC sp_executesql oluşturulmuş UPDATE Beyan. - cassandrad
Asıl cevap, kontrol ettiğiniz veri tabanını eklemeniz gerektiğidir. FROM [YourDatabase].INFORMATION_SCHEMA.COLUMNS - Alex Kwitny


Cevaplar:


SQL Server 2005'ten itibaren:

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

1729
2017-09-25 12:39



Ya da bazı yazım ve kullanımları kaydedebilirsiniz IF COL_LENGTH('tableName', 'columnName') IS NOT NULL - Martin Smith
@Mitch - Dokümanlara göre geri dönecek NULL Kullanıcının meta verileri görüntüleme izni yoksa sys.columns kullanıcı erişimini de kontrol eder. - Martin Smith
@MitchWheat -> Varsa, select * yerine söylemek istiyorum, eğer sys.columns'dan 1'i kullanırdım, böylece bir dizi satır yerine sadece bir skaler değer döndürür. senin düşüncelerin ? - vijaysylvester
Bu açık olabilir, ancak tablo dbo'dan farklı bir şemadaysa şemayı adın bir parçası olarak yazmalısınız: ... AND [object_id] = OBJECT_ID(N'schemaName.tableName' ...) Bunu yapmazsanız, sütun mevcut olsa bile sorguda satır döndürmemesine neden olur. - user1778770
@MitchWheat, 1658 kişiye buggy tavsiyesinde bulunduğunuzu ve çoğunuzun sizin kodunuzda potansiyel hatalar yaptığını söyledi. Hala cevap vermediniz ya da açık bir şekilde gösterildiğim durumda sunulan yöntemimin yönteminizin yanlış olduğunu kontrol ettiniz: oi63.tinypic.com/2mopgyc.jpg. Normal olarak uygulanan sunucu hakları hiyerarşisi ile herhangi bir yordamda çalışmaz. Yani, lütfen demagogy'ı durdurun ve sadece "çözümün" resmimdeki gerçek kullanım durumunu deneyin. Öyleyse özür dileyin ve cevabınızı düzenleyin, insanlara tavsiye önerisini durdurun. Bu benim son yorumum. İyi derece avı var. - Juozas


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 yanıtın tamamı için geçerli değildir.

İlk parametre tablosu adı olduğunu unutmayın. COL_LENGTH Gerektiğinde bir, iki veya üç bölümlü ad biçiminde olabilir.

Tabloyu farklı bir veritabanında referans alan bir örnek

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

Meta veri görünümlerini kullanmayla karşılaştırıldığında bu yanıtla bir fark, metadata işlevlerinin COL_LENGTH Her zaman sadece, etkilenen izolasyon seviyesinden bağımsız olarak, taahhüt edilen değişiklikler hakkındaki verileri döndürür.


854
2018-03-20 14:47



Bu, diğer cevapların bazılarından daha az okunabilir, muhtemelen neden bu kadar yüksek değil. - Bill Yang
@Bill - Ne şekilde daha az okunabilir? Firefox'ta güzel görünüyor. Bu cevap, kabul edilene göre 2 yıldan daha uzun bir sürede yayınlandı ve bu da IMO notunu açıkladı. Varlık olduğunu daha az açık olarak ifade ettiyseniz, bu tür bir deyim SQL Server'da oldukça yaygındır. Örneğin. kullanma IF OBJECT_ID('TableName','U') IS NULL nesne varlığını kontrol etmek veya DB_ID('foo') veritabanı varlığını kontrol etmek için. - Martin Smith
@MartinSmith Eminim daha az okunabilir anlamına geliyordu çünkü eğer bu deyimi bilmiyorsanız ve bu kodu bir başkasından devralmışsanız, kodun ne olduğunu hemen anlamayacaksınız. Tür yazma gibi x>>2 yerine x/4 C ++ 'da. Daha ayrıntılı kod (if exists (select column_name from information_schema ...)) çok daha fazla yer kaplıyor, ama kimse ne yaptığını anlamaya çalışmak için kafalarını çizemezdi. - Kip
Daha fazla özlü yanı sıra bu daha hızlı bir çözümdür. erişme INFORMATION_SCHEMA veya sys.columns diski vurur COL_LENGTH önbelleğe alınmış veritabanı meta verilerini kullanır. - wqw
Bu muhtemelen en yüksek puanlı cevap değil, diğerinden 2.5 yıl sonra verildi. Bu yüzden her zaman iki cevaptaki puanları karşılaştırırken tarihleri ​​kontrol ediyorum. Daha önce verilen bir cevabın üstesinden gelmek çok daha uzun sürer. ;) - Sean


Özel gereksinimlerinize uyacak şekilde aşağıdakileri yapın:

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

Sorgulanacak düzenlemeyle başa çıkmak için Düzenle: Bu işe yarar - aptal hatalar için kodunuzu dikkatli bir şekilde ele alın; Örneğin eklediğiniz gibi aynı veritabanında INFORMATION_SCHEMA'yı mı soruyorsunuz? Tablo / sütun adınızda herhangi bir ifadede yazım hatası var mı?


125
2017-09-25 12:35



Sadece, makalenin sorunu giderdikten sonra TABLE_SCHEMA = 'mySchema' ekleme işlemini öğrendim. - Maciej
-1: OP'nin sorusuna cevap vermez, OP'nin yorumuna hitap etmeyen OP'ye rağmen yeni bir collumn eklemenin yeni bilgisini ekler. - ANeves


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

63
2017-09-25 12:35



Bu yöntem ayrıca, SQL CE ile çalışır, belirtilen diğer yöntemlerin bazıları değil. - Sandra Walters
Kullanabilirsiniz SELECT 1 yerine SELECT TOP 1 1 ). - shA.t
İçinde EXISTS SQL deyimi otomatik olarak sütunları (örneğin count(*)) yani SELECT * yeterli olacaktır. - Marc L.


Tercih ederim INFORMATION_SCHEMA.COLUMNS Microsoft, sistem tablolarını sürümler arasında korumayı garanti etmediği için bir sistem tablosu üzerinde. Örneğin, dbo.syscolumns hala SQL 2008'de çalışıyor, ancak kullanımdan kaldırılıyor ve gelecekte herhangi bir zamanda kaldırılabiliyor.


43
2018-06-26 08:58



"Tüm yeni özellikler için güncellenmediği için INFORMATION_SCHEMA görünümleri eksik olabilir" - onedaywhen
Evet, o zamandan beri söylemez INFORMATION_SCHEMA görünümler yalnızca ANSI standart metadata içerir. Ancak, bu bir varlık testi için yeterlidir. - Christian Hayter
Microsoft, "SQL Server'ın gelecekteki sürümlerinde, Microsoft, sütun listesinin sonuna sütunlar ekleyerek herhangi bir sistem kataloğu görünümünün tanımını artırabilir. SELECT * FROM sys.catalog_view_name sözdizimini üretim kodunda kullanmamanızı öneririz. Geri dönen sütunlar uygulamanızı değiştirebilir ve bozabilir. " Bu, sütunları kaldırmayacaklarını veya siparişlerini değiştirmeyeceklerini ima eder. Bu, tüm kenar durumları için yeterince geriye dönük uyumluluk. - siride


İlgilendiğiniz tablolarla ilgili 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

Ayrıca, Information_schema görünümlerini kullanarak, görünümleri, saklı yordamları ve veritabanıyla ilgili hemen hemen her şeyi sorgulayabilirsiniz.


38
2017-09-25 12:37





İlk önce table/column(id/name) kombinasyon var dbo.syscolumns (alan tanımlarını içeren bir iç SQL Server tablosu) ve uygun değilse ALTER TABLE eklemek için sorgu. Ö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
2017-09-25 12:38





Şunun gibi 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 böyle 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'te çalışmalıdır. SQL Server 2008'den emin değilim, ancak neden görmediğinizi görmeyin.


26
2018-05-01 04:46





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

İçinde SQL Server 2016 büyük yerine yeni DIE deyimlerini kullanabilirsiniz IF sarmalayıcıları

ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name

24
2018-03-03 15:49





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
2018-03-20 22:27





İyi bir arkadaşım ve meslektaşım bana nasıl kullanabileceğinizi gösterdi IF SQL işlevleriyle engelleme OBJECT_ID ve COLUMNPROPERTY bir sütun denetlemek için SQL SERVER 2005+ içinde. Aşağıdakine benzer bir şey kullanabilirsiniz:

Kendiniz için burada 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

21
2017-08-02 19:54



Tabii ki, tablonun var olduğundan eminseniz, durumun ilk bölümünü dışarıda bırakıp kontrol edebilirsiniz. COLUMNPROPERTY bir tek. - Ruud Helderman