SQL Serverテーブルに列が存在するかどうかを確認するにはどうすればよいですか?


1853

特定の列が存在しない場合は、追加する必要があります。次のようなものがありますが、常にfalseを返します。

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

SQL Serverデータベースのテーブルに列が存在するかどうかを確認するにはどうすればよいですか?


12
私は実際には問題のコードに問題があるとは思いません:2008 R2で私にとってはうまく機能します。(多分あなたは間違ったデータベースでそれを実行していましたか?多分あなたのデータベースは大文字と小文字を区別し、myTableName / myColumnName文字列で大文字と小文字が正しくありませんでした?このタイプのクエリはCOL_LENGTHソリューションよりも柔軟性があるようです:できる"INFORMATION_SCHEMA"を適切にプレフィックスすることにより、別のデータベースに対しても、データベースリンクに対しても実行できます。COL_LENGTHメタデータ関数を使用してその方法を確認できませんでした
mwardm

3
@mwardm-正常にCOL_LENGTH('AdventureWorks2012.HumanResources.Department ','ModifiedDate')動作します。
マーティンスミス

6
少し関連するヒント:列を追加した直後に列を更新する場合(多くのユーザーがこの目的でこの記事を検索していたと思います)、EXEC sp_executesql形成されたUPDATEステートメントで使用できます。
cassandrad

実際の答えは、チェック対象のデータベースを追加する必要があるということですFROM [YourDatabase].INFORMATION_SCHEMA.COLUMNS
Alex Kwitny

回答:


2054

SQL Server 2005以降:

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

マーティン・スミスのバージョンは短いです:

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

マーティン・スミスのバージョンでは、大括弧[]内にcolumnNameを含めないことが1つ言及されています。columnNameが角括弧[]内にある場合、列がテーブルに存在していてもnullになります
Hemendra

@HemendraSinghChauhan-名前の一部ではないためです。名前と比較するときにも、それを見つけるsys.columns
マーティン・スミス

@MartinSmithはそれを知らなかった、私はあなたの答えを使っていて、これに出くわしました。通常、列の追加中に角括弧を使用するため、COL_LENGTH関数内でも使用しました。私のコードは次のようなものでした:Alter table Table_Name Add [ColumnName] NVarchar(max) NULL; Select COL_LENGTH('[TABLE_NAME]', '[COLUMN_NAME]')
Hemendra

はい、それは無効です。の引数はCOL_LENGTH引用符で囲む必要があります。誰かが実際に名前を持っている列を作成することは理論的には可能です[COLUMN_NAME]-たとえばCREATE TABLE #T([[COLUMN_NAME]]] INT); SELECT * FROM #T、これが規則でないと曖昧になります。
Martin Smith

987

より簡潔なバージョン

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

メタデータを表示する権限に関するポイントは、これだけでなくすべての回答に適用されます。

最初のパラメータテーブル名はCOL_LENGTH、必要に応じて、1つ、2つ、または3つの部分からなる名前形式にすることができます。

別のデータベースのテーブルを参照する例は次のとおりです。

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

メタデータビューの使用と比較したこの回答との1つの違いは、メタデータ関数COL_LENGTH(有効な分離レベルに関係なく、常にコミットされた変更に関するデータのみを返すなど)です。


11
これは他のいくつかの回答よりも読みにくく、おそらくそれほど高く評価されていないのでしょう。
Bill Yang、

38
@ビル-どのように読みにくいですか?Firefoxでは問題なく見えます。この回答は、IMOの評価を説明する、承認された回答より2年以上遅れて投稿されました。存在チェックであることがあまり明確でない場合は、このタイプのイディオムはSQL Serverでは非常に一般的です。たとえば、IF OBJECT_ID('TableName','U') IS NULLオブジェクトの存在DB_ID('foo')を確認したり、データベースの存在を確認したりするために使用します。
マーティン・スミス

59
@MartinSmithこのイディオムを知らず、他の誰かからこのコードを継承した場合、コードが何をするのかすぐに理解できないため、彼は読みやすさを低下させたと確信しています。C ++のx>>2代わりに書くようなものx/4です。より冗長なコード(if exists (select column_name from information_schema ...))はより多くのスペースを必要としますが、それが何であるかを理解しようとして頭を掻く人は誰もいません。
キップ

22
より簡潔なことに加えて、これはより高速なソリューションです。キャッシュされたデータベースメタデータを使用しながら、INFORMATION_SCHEMAビューにアクセスしたりsys.columnsディスクにアクセスしたりするCOL_LENGTH
wqw 2014年

7
これは、他の回答から2.5年後に与えられたため、おそらく最も高い評価の回答ではありません。そのため、2つの回答の評価を比較するときは常に日付を確認します。ずっと以前に与えられた答えを克服するのには、ずっと長い時間がかかります。;)
Sean

149

特定の要件に合わせて以下を調整します。

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

質問への編集に対処するための編集:それはうまくいくはずです-愚かな間違いについてコードを注意深く調べてください。たとえば、挿入が適用されているのと同じデータベースでINFORMATION_SCHEMAにクエリを実行していますか?どちらのステートメントでも、テーブル/列名にタイプミスがありますか?


3
where句の後にTABLE_SCHEMA = 'mySchema'を追加すると問題が解決することがわかりました。
Maciej

12
-1:OPの質問に回答せず、OPがまったく質問しないにもかかわらず、新しい列を追加する方法に関する新しい情報を追加するだけで、OPのコメントには対応しません。
ANeves、2011年

1
+1はOPの質問に完全に回答し、OPが次にとるべき追加情報のボーナスを提供します。そして、これは私が探していたものでした。
Bitterblue

74

これを試して...

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
この方法はSQL CEでも機能しますが、言及されている他の方法の一部は機能しません。
SWalters-モニカを2013年

9
;)のSELECT 1代わりに使用できますSELECT TOP 1 1
shA.t 2015年

4
EXISTSステートメント内では、SQLは自動的に列を最適化します(と同様count(*))でSELECT *十分です。
マーク

完全を期すためand [TABLE_SCHEMA] = '???'に、WHERE句への追加を検討する必要があります。
Andrew Jens

51

カラムの存在を確認している方は落としてください。

SQL Server 2016から、大きなIFラッパーの代わりに新しいDIEステートメントを使用できます

ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name

47

INFORMATION_SCHEMA.COLUMNSMicrosoftはバージョン間でシステムテーブルを保持することを保証していないため、システムテーブルよりも好みます。たとえば、dbo.syscolumnsはSQL 2008でも機能しますが、非推奨であり、将来いつでも削除される可能性があります。



5
ええ、もちろん、INFORMATION_SCHEMAビューにはANSI標準のメタデータしか含まれていないため、言うまでもありません。ただし、存在テストにはそれで十分です。
クリスチャンヘイター2013

3
Microsoftは、「SQL Serverの将来のリリースでは、列リストの最後に列を追加することにより、システムカタログビューの定義を拡張する可能性があります。本番コードで構文SELECT * FROM sys.catalog_view_name返される列が変更され、アプリケーションが壊れる可能性があります。」つまり、列を削除したり、順序を変更したりすることはありません。これは、エッジケース以外のすべてに対して十分な下位互換性があります。
シリド

42

情報スキーマシステムビューを使用して、興味のあるテーブルについてほとんど何でも見つけることができます。

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

また、Information_schemaビューを使用して、ビュー、ストアドプロシージャ、およびデータベースに関するほとんどすべてを問い合わせることができます。


これはまさにアンケートが使用しているものであり、存在しない場合に列を追加する方法を知る必要がありました。
Birel

35

次のようなものを試してください:

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

次に、次のように使用します。

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

SQL Server 2000とSQL Server 2005の両方で動作するはずです。SQLServer 2008については不明ですが、なぜそうなのかわかりません。


34

table/ columnid/ name)の組み合わせがdbo.syscolumns(フィールド定義を含む内部SQL Serverテーブル)に存在するかどうかを確認し、存在しない場合は適切なALTER TABLEクエリを発行して追加します。例えば:

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

28

私の親友と同僚はIF、SQL関数OBJECT_IDCOLUMNPROPERTYSQL SERVER 2005+でブロックを使用して列を確認する方法も教えてくれました。次のようなものを使用できます。

あなたはここであなた自身のために見ることができます

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
そしてもちろん、テーブルが存在することを確信している場合は、条件の最初の部分を省略して、チェックCOLUMNPROPERTYのみすることができます。
Ruud Helderman 14

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

これは私にとってSQL 2000でうまくいきました:

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

21

これを試して

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

INFORMATION_SCHEMA.TABLES特定のテーブルの列は必要なく、フィルタリングもしないので、別のテーブルの同じ列名に対して複数の行が返される場合があります;)。
shA.t 2015年

19

SQL SERVER 2000にも同様のものが必要でしたが、@ Mitchが指摘しているように、これは2005以降でのみ機能します。

それが他の誰かを助けるならば、これは結局私にとってうまくいったものです:

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
table_schema = 'schema_name'のことだと思います。
タブアレマン2014

11

受け入れられた回答の一時テーブルバージョン:

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

1
それは受け入れられた答えとどう違うのですか?受け入れられた回答で一時テーブルが機能しませんか?
John Saunders

1
正しい。「sys.columns」を「tempdb.sys.columns」として指定する必要があり、テーブル名の前に「tempdb ..」を付ける必要があるため、受け入れられた回答は一時テーブルでは機能しません。
crokusek 2015年

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

8

Wheatの答えは適切ですが、スキーマまたはデータベースに同じテーブル名と列名のペアがないことを前提としています。その状態に対して安全にするために、これを使用してください...

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

8

列の存在を確認するには、いくつかの方法があります。INFORMATION_SCHEMA.COLUMNSユーザーとのコミュニケーションのために作成されたものを使用することを強くお勧めします。次の表を検討してください。

 sys.objects
 sys.columns

確認できる他のアクセス方法もいくつかあります system catalog.

また、を使用する必要はなくSELECT *、単にそれをテストしますNULL value

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

1
どんなにも、あなたの場合SELECT *EXISTS使用されて存在する場合、それは本当に存在のすべての行とすべての列、内部的にそれだけでチェックを選択しないと、すべての行と列のためではない、実際にチェックしないため、
Pawan Nogariya

7

最もシンプルで理解しやすいソリューションの1つは次のとおりです。

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

以下は、データベースの列の追加を管理するために使用する簡単なスクリプトです。

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

この例では、NameColumnName追加されるでObject_Idあり、TableName


4

以下のクエリを使用して、検索された列がテーブルに存在するかどうかを確認できます。以下のように、検索結果から判断することもできます。

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

さらに別のバリエーション...

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

1

table-> script table as-> new windows-あなたはデザインスクリプトを持っています。新しいウィンドウで列名を確認して見つける


1

以下のクエリを実行して、指定したテーブルに列が存在するかどうかを確認します。

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

別の貢献は、存在しない場合に列を追加する次のサンプルです。

    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

それが役に立てば幸い。シモーネ


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

これは、この問題をかなり簡単に解決する簡単な方法です。同様のシナリオでこれを複数回使用しました。それは魅力のように機能します。


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

列が存在しない場合は、何かを行います。

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

列が存在する場合は何かを行います。

BEGIN
    IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NOT NULL)
    BEGIN
        //Do something
    END
END;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.