Bagaimana memeriksa apakah ada kolom dalam tabel SQL Server?

1853

Saya perlu menambahkan kolom tertentu jika tidak ada. Saya memiliki sesuatu seperti berikut ini, tetapi selalu mengembalikan false:

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

Bagaimana saya bisa mengecek jika ada kolom dalam tabel database SQL Server?

Maciej
sumber
12
Saya sebenarnya tidak berpikir ada yang salah dengan kode dalam pertanyaan: Bekerja dengan baik untuk saya di 2008 R2. (Mungkin Anda menjalankannya di database yang salah? Mungkin basis data Anda peka terhadap huruf besar-kecil dan Anda tidak memiliki huruf besar-kecil di string myTableName / myColumnName Anda? Jenis kueri ini tampaknya lebih fleksibel daripada solusi COL_LENGTH: Saya dapat untuk menjalankannya terhadap basis data yang berbeda dan bahkan melalui tautan basis data dengan mengawali dengan tepat "INFORMATION_SCHEMA". Tidak dapat melihat bagaimana melakukannya dengan fungsi metadata COL_LENGTH.
mwardm
3
@mwardm - COL_LENGTH('AdventureWorks2012.HumanResources.Department ','ModifiedDate')berfungsi dengan baik.
Martin Smith
6
Sedikit petunjuk terkait: jika Anda ingin memperbarui kolom setelah penambahan kolom (saya percaya banyak pengguna mencari artikel ini untuk tujuan itu), Anda dapat menggunakan EXEC sp_executesqldengan UPDATEpernyataan yang dibentuk .
cassandrad
Jawaban sebenarnya adalah Anda harus menambahkan database yang Anda periksa sehingga ituFROM [YourDatabase].INFORMATION_SCHEMA.COLUMNS
Alex Kwitny

Jawaban:

2054

SQL Server 2005 dan seterusnya:

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

Versi Martin Smith lebih pendek:

IF COL_LENGTH('schemaName.tableName', 'columnName') IS NOT NULL
BEGIN
    -- Column Exists
END
Mitch Wheat
sumber
Dalam versi Martin Smith, satu hal yang perlu disebutkan adalah tidak memasukkan nama kolom dalam tanda kurung []. Ketika columnName ada di dalam tanda kurung siku [], itu akan memberikan nol bahkan jika kolom ada di tabel
Hemendra
@HemendraSinghChauhan - itu karena mereka bukan bagian dari nama. Anda juga akan menemukan bahwa ketika membandingkan dengan nama disys.columns
Martin Smith
@ MartinSmith tidak tahu itu, saya menggunakan jawaban Anda dan menemukan ini. Secara umum saya menggunakan tanda kurung siku selama menambahkan kolom, jadi saya menggunakannya di dalam fungsi COL_LENGTH juga. Kode saya seperti ini:Alter table Table_Name Add [ColumnName] NVarchar(max) NULL; Select COL_LENGTH('[TABLE_NAME]', '[COLUMN_NAME]')
Hemendra
ya itu tidak valid. Argumen yang COL_LENGTHperlu dikutip. Secara teori dimungkinkan bagi seseorang untuk membuat kolom yang benar-benar memiliki nama [COLUMN_NAME]- misalnya CREATE TABLE #T([[COLUMN_NAME]]] INT); SELECT * FROM #Tdan kemudian akan ambigu jika ini bukan aturannya.
Martin Smith
987

Versi yang lebih ringkas

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

Poin tentang izin untuk melihat metadata berlaku untuk semua jawaban, bukan hanya yang ini.

Perhatikan bahwa nama tabel parameter pertama COL_LENGTHbisa dalam satu, dua, atau tiga format nama bagian sesuai kebutuhan.

Contoh referensi tabel dalam database berbeda adalah

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

Satu perbedaan dengan jawaban ini dibandingkan dengan menggunakan tampilan metadata adalah bahwa fungsi metadata seperti COL_LENGTHselalu hanya mengembalikan data tentang perubahan yang dilakukan terlepas dari tingkat isolasi yang berlaku.

Martin Smith
sumber
11
Ini kurang dapat dibaca daripada beberapa jawaban lain, mungkin mengapa itu tidak dinilai tinggi.
Bill Yang
38
@ Bill - Kurang bisa dibaca dengan cara apa? Terlihat bagus di Firefox. Jawaban ini diposting lebih dari 2 tahun kemudian daripada yang diterima, yang menjelaskan peringkat IMO. Jika maksud Anda kurang jelas bahwa itu adalah keberadaan periksa idiom jenis ini cukup umum di SQL Server. misalnya menggunakan IF OBJECT_ID('TableName','U') IS NULLuntuk memeriksa keberadaan objek atau DB_ID('foo')untuk memeriksa keberadaan database.
Martin Smith
59
@ MartinSmith Saya yakin maksudnya kurang mudah dibaca karena jika Anda tidak tahu idiom ini, dan Anda mewarisi kode ini dari orang lain, Anda tidak akan langsung mengerti apa yang dilakukan oleh kode tersebut. Jenis suka menulis x>>2daripada x/4di C ++. Kode verbose yang lebih banyak ( if exists (select column_name from information_schema ...)) membutuhkan lebih banyak ruang, tetapi tidak ada yang akan menggaruk kepala mereka mencoba mencari tahu apa yang dilakukannya.
Kip
22
Selain lebih ringkas, ini adalah solusi yang lebih cepat. Mengakses INFORMATION_SCHEMAtampilan atau sys.columnshits disk, saat COL_LENGTHmenggunakan metadata database yang di-cache.
wqw
7
Ini mungkin bukan jawaban yang berperingkat paling tinggi karena diberikan 2,5 tahun setelah yang lain. Itu sebabnya saya selalu memeriksa tanggal ketika membandingkan peringkat pada dua jawaban. Dibutuhkan jauh lebih lama untuk mengatasi jawaban yang diberikan jauh sebelumnya. ;)
Sean
149

Tweak di bawah ini untuk memenuhi kebutuhan spesifik Anda:

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

Sunting untuk menangani sunting untuk pertanyaan : Itu seharusnya berhasil - perhatikan dengan teliti kode Anda untuk kesalahan bodoh; apakah Anda menanyakan INFORMATION_SCHEMA pada basis data yang sama dengan penyisipan Anda diterapkan misalnya? Apakah Anda memiliki salah ketik di tabel / nama kolom di salah satu pernyataan?

Luke Bennett
sumber
3
Saya baru tahu bahwa menambahkan TABLE_SCHEMA = 'mySchema' setelah klausa memperbaiki masalah.
Maciej
12
-1: tidak menjawab pertanyaan OP, hanya menambahkan informasi baru tentang cara menambahkan kolom baru meskipun OP tidak menanyakan hal itu sama sekali, tidak menanggapi komentar OP.
ANeves
1
+1 Menjawab pertanyaan OP dengan sempurna dengan bonus informasi tambahan yang OP akan lakukan selanjutnya. Dan inilah yang saya cari.
Bitterblue
74

Coba ini...

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
Leon Tayson
sumber
6
Metode ini juga berfungsi dengan SQL CE, sedangkan beberapa metode lain yang disebutkan tidak.
SWalters
9
Anda bisa menggunakan SELECT 1bukan SELECT TOP 1 1;).
shA.t
4
Dalam sebuah EXISTSpernyataan, SQL secara otomatis mengoptimalkan kolom menjauh (seperti count(*)) sehingga SELECT *cukup.
Marc L.
Demi kelengkapan, Anda harus mempertimbangkan menambahkan and [TABLE_SCHEMA] = '???'klausa WHERE.
Andrew Jens
51

Bagi orang yang memeriksa keberadaan kolom untuk menjatuhkannya.

Dari SQL Server 2016 Anda dapat menggunakan pernyataan DIE baru alih-alih IFpembungkus besar

ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name
P ரதீப்
sumber
47

Saya lebih suka INFORMATION_SCHEMA.COLUMNStabel sistem karena Microsoft tidak menjamin untuk menjaga tabel sistem antar versi. Sebagai contoh, dbo.syscolumnsmasih bekerja di SQL 2008, tetapi sudah usang dan dapat dihapus kapan saja di masa depan.

Christian Hayter
sumber
5
Ya, itu tidak perlu dikatakan lagi karena INFORMATION_SCHEMAview hanya berisi metadata standar ANSI. Namun, itu sudah cukup untuk tes keberadaan.
Christian Hayter
3
Microsoft mengatakan "Dalam rilis SQL Server yang akan datang, Microsoft dapat menambah definisi tampilan katalog sistem dengan menambahkan kolom ke akhir daftar kolom. Kami menyarankan agar Anda tidak menggunakan sintaks SELECT * FROM sys.catalog_view_name dalam kode produksi karena jumlah kolom yang dikembalikan dapat mengubah dan menghancurkan aplikasi Anda. " Itu menyiratkan bahwa mereka tidak akan menghapus kolom atau mengubah pesanan mereka. Itu kompatibilitas mundur yang cukup baik untuk semua kecuali kasus tepi.
siride
42

Anda dapat menggunakan tampilan sistem skema informasi untuk mengetahui cukup banyak tentang tabel yang Anda minati:

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

Anda juga dapat menginterogasi tampilan, prosedur tersimpan dan cukup banyak tentang database menggunakan tampilan Information_schema.

anonim
sumber
Inilah yang digunakan kuesioner, dia perlu tahu bagaimana cara menambahkan kolom jika tidak ada.
Birel
35

Coba sesuatu seperti:

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

Kemudian gunakan seperti ini:

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

Ini harus bekerja pada SQL Server 2000 & SQL Server 2005. Tidak yakin tentang SQL Server 2008, tetapi tidak melihat mengapa tidak.

Matt Lacey
sumber
34

Pertama periksa apakah kombinasi table/ column( id/ name) ada di dbo.syscolumns(tabel SQL Server internal yang berisi definisi bidang), dan jika tidak mengeluarkan ALTER TABLEkueri yang sesuai untuk menambahkannya. Sebagai contoh:

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

Seorang teman baik dan kolega saya menunjukkan kepada saya bagaimana Anda juga dapat menggunakan IFblok dengan fungsi SQL OBJECT_IDdan COLUMNPROPERTYdalam SQL SERVER 2005+ untuk memeriksa kolom. Anda dapat menggunakan sesuatu yang mirip dengan yang berikut ini:

Anda dapat melihatnya sendiri di sini

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
brazilianldsjaguar
sumber
1
Dan tentu saja, jika Anda yakin bahwa tabel itu ada, Anda dapat mengabaikan bagian pertama dari kondisi dan COLUMNPROPERTYhanya memeriksa .
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
Tuomo Kämäräinen
sumber
22

Ini bekerja untuk saya di SQL 2000:

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

Coba ini

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') 
Douglas Tondo
sumber
Anda tidak perlu INFORMATION_SCHEMA.TABLESdan Anda tidak memfilter kolom untuk tabel tertentu, sehingga terkadang akan mengembalikan lebih dari satu baris untuk nama kolom yang sama di tabel terpisah;).
shA.t
19

Saya perlu serupa untuk SQL SERVER 2000 dan, seperti yang ditunjukkan oleh @Mitch, ini hanya berfungsi pada 2005+.

Jika itu membantu orang lain, inilah yang pada akhirnya berhasil bagi saya:

if exists (
    select * 
    from 
        sysobjects, syscolumns 
    where 
        sysobjects.id = syscolumns.id 
        and sysobjects.name = 'table' 
        and syscolumns.name = 'column')
FrostbiteXIII
sumber
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
BYRAKUR SURESH BABU
sumber
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;
Na30m
sumber
2
Saya pikir Anda maksud table_schema = 'schema_name'.
Tab Alleman
11

Versi tabel temporer dari jawaban yang diterima :

if (exists(select 1 
             from tempdb.sys.columns  
            where Name = 'columnName'
              and Object_ID = object_id('tempdb..#tableName')))
begin
...
end
crokusek
sumber
1
Apa bedanya dengan jawaban yang diterima? Apakah tabel temp tidak berfungsi dalam jawaban yang diterima?
John Saunders
1
Benar. Jawaban yang diterima tidak berfungsi untuk tabel temp karena 'sys.columns' harus ditentukan sebagai 'tempdb.sys.columns' dan nama tabel harus didahului oleh 'tempdb ..'.
crokusek
10
select distinct object_name(sc.id)
from syscolumns sc,sysobjects so  
where sc.name like '%col_name%' and so.type='U'
Nishad
sumber
8

Jawaban gandum bagus, tetapi anggap Anda tidak memiliki pasangan nama tabel / nama kolom yang identik dalam skema atau basis data apa pun. Untuk membuatnya aman untuk kondisi itu gunakan ini ...

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

Ada beberapa cara untuk memeriksa keberadaan kolom. Saya akan sangat menyarankan untuk digunakan INFORMATION_SCHEMA.COLUMNSkarena dibuat untuk berkomunikasi dengan pengguna. Pertimbangkan tabel berikut:

 sys.objects
 sys.columns

dan bahkan beberapa metode akses lain yang tersedia untuk diperiksa system catalog.

Juga, tidak perlu digunakan SELECT *, cukup mengujinya denganNULL value

IF EXISTS(
           SELECT NULL 
           FROM INFORMATION_SCHEMA.COLUMNS
           WHERE
             TABLE_NAME = 'myTableName'
             AND COLUMN_NAME = 'myColumnName'
         ) 
Ali Elmi
sumber
1
Tidak masalah bahkan jika Anda SELECT *dengan EXISTS, karena ketika ada digunakan itu tidak benar-benar memilih semua baris dan semua kolom, secara internal hanya memeriksa keberadaan dan tidak benar-benar memeriksa semua baris dan kolom
Pawan Nogariya
7

Salah satu solusi paling sederhana dan mudah dipahami adalah:

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
Arsman Ahmad
sumber
7

Berikut ini adalah skrip sederhana yang saya gunakan untuk mengelola penambahan kolom dalam 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

Dalam contoh ini, Nameadalah ColumnNameuntuk ditambahkan dan Object_IdadalahTableName

UJS
sumber
4

Kueri di bawah ini dapat digunakan untuk memeriksa apakah kolom yang dicari ada di tabel atau tidak. Kami dapat mengambil keputusan berdasarkan hasil yang dicari juga seperti yang ditunjukkan di bawah ini.

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
Suraj Kumar
sumber
3

Namun variasi lain ...

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

tabel -> skrip tabel sebagai -> jendela baru - Anda memiliki skrip desain. periksa dan temukan nama kolom di jendela baru

arnav
sumber
1

Jalankan kueri di bawah ini untuk memeriksa apakah kolom ada di tabel yang diberikan:

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';
S Krishna
sumber
1

Kontribusi lain adalah contoh berikut yang menambahkan kolom jika tidak ada.

    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

Semoga ini bisa membantu. Simone

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

Ini harus menjadi cara yang cukup mudah dan solusi langsung untuk masalah ini. Saya telah menggunakan ini beberapa kali untuk skenario serupa. Itu bekerja seperti pesona, tidak ada keraguan tentang itu.

Ilangeeran
sumber
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
Mohamad Reza Shahrestani
sumber
0

Lakukan sesuatu jika kolom tidak ada:

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

Lakukan sesuatu jika kolom ada:

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