如何检查SQL Server表中是否存在列?

时间:2008-09-25 12:34:00

标签: sql-server sql-server-2008 tsql sql-server-2012 sql-server-2016

如果不存在,我需要添加一个特定的列。我有类似以下内容,但它总是返回false:

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

如何检查SQL Server数据库的表中是否存在列?

31 个答案:

答案 0 :(得分:1894)

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

Martin Smith的版本更短:

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

答案 1 :(得分:921)

更简洁的版本

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的第一个参数表名称可以根据需要采用一个,两个或三个部分名称格式。

引用不同数据库中的表的示例是

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

与使用元数据视图相比,这个答案的一个区别是,COL_LENGTH等元数据函数始终只返回有关已提交更改的数据,而不管有效的隔离级别。

答案 2 :(得分:131)

根据您的具体要求调整以下内容:

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 :(得分:68)

试试这个......

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

答案 4 :(得分:44)

我更喜欢INFORMATION_SCHEMA.COLUMNS而不是系统表,因为Microsoft不保证在版本之间保留系统表。例如,dbo.syscolumns在SQL 2008中仍然可以使用,但它已被弃用,并且可以在将来的任何时候删除。

答案 5 :(得分:40)

您可以使用信息架构系统视图来查找您感兴趣的表格的几乎任何内容:

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

您还可以使用Information_schema视图查询视图,存储过程以及有关数据库的任何内容。

答案 6 :(得分:31)

首先检查table(包含字段定义的内部SQL Server表)中是否存在column / idname / dbo.syscolumns)组合,如果没有发出适当的ALTER TABLE查询来添加它。例如:

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

答案 7 :(得分:29)

尝试类似:

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.不确定SQL Server 2008,但不明白为什么不。

答案 8 :(得分:29)

对于正在检查列存在的人来说。

SQL Server 2016 中,您可以使用新的DIE语句而不是大IF包装器

ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name

答案 9 :(得分:24)

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

答案 10 :(得分:24)

我的一位好朋友和同事向我展示了如何在SQL SERVER 2005+中使用SQL函数IFOBJECT_ID的{​​{1}}块来检查列。您可以使用类似于以下内容的内容:

You can see for yourself here

COLUMNPROPERTY

答案 11 :(得分:21)

这在SQL 2000中对我有用:

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

答案 12 :(得分:20)

试试这个

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

答案 13 :(得分:17)

我需要类似于SQL SERVER 2000,正如@Mitch指出的那样,这只适用于2005 +。

它应该帮助其他人,这最终对我有用:

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

答案 14 :(得分:14)

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

答案 15 :(得分:10)

IF NOT EXISTS( SELECT NULL
            FROM INFORMATION_SCHEMA.COLUMNS
           WHERE table_name = 'tablename'
             AND table_schema = 'db_name'
             AND column_name = 'columnname')  THEN

  ALTER TABLE `TableName` ADD `ColumnName` int(1) NOT NULL default '0';

END IF;

答案 16 :(得分:9)

accepted answer的临时表版本:

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

答案 17 :(得分:9)

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

答案 18 :(得分:6)

Wheat的答案很好,但假设您在任何架构或数据库中没有任何相同的表名/列名对。为了使该条件安全,请使用此...

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

答案 19 :(得分:6)

有几种方法可以检查列的存在。 我强烈建议在创建时使用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'
         ) 

答案 20 :(得分:5)

这是一个用于管理数据库中列添加的简单脚本:

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

在此示例中,Name是要添加的ColumnNameObject_IdTableName

答案 21 :(得分:5)

最简单易懂的解决方案之一是:

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

答案 22 :(得分:3)

以下查询可用于检查表中是否存在搜索列。我们也可以根据搜索结果做出决定,如下所示。

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

答案 23 :(得分:3)

//Only checks
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

答案 24 :(得分:2)

另一种变化......

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

答案 25 :(得分:0)

表->脚本表为->新窗口-您具有设计脚本。 检查并在新窗口中找到列名

答案 26 :(得分:0)

执行以下查询以检查给定表中是否存在该列:

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

答案 27 :(得分:0)

print (df)
       id  region  201801  201802  201803  201804  201805  201806  201807  \
0  100001     628     NaN     NaN     NaN     NaN     NaN     NaN     NaN   
1  100002    1149    27.0    24.0    27.0    25.0    24.0    26.0    27.0   
2  100003    1290    26.0    26.0    26.0    26.0    23.0    27.0    27.0   
3  100004     955    25.0    26.0    26.0    24.0    24.0    26.0    28.0   
4  100005    1397    15.0    25.0    26.0    24.0    21.0    27.0    27.0   
5  100006    1397    15.0    25.0    26.0    24.0    21.0    27.0    27.0   

   201808  ...  201811  201812  201901  201902  201903  201904  201905  \
0     NaN  ...      24    20.0    26.0    24.0    26.0    26.0    26.0   
1    28.0  ...      24    21.0    26.0    25.0    27.0    24.0    26.0   
2     NaN  ...      28     NaN    28.0    26.0    27.0    27.0    27.0   
3    27.0  ...      24    12.0     NaN     NaN     NaN     NaN     NaN   
4    26.0  ...      25     NaN     NaN     NaN     NaN     NaN     NaN   
5    26.0  ...      25    23.0    25.0    17.0     NaN     NaN     NaN   

   201906  date_begin   date_end  
0    23.0  2019-01-01 2262-04-11  
1    24.0  2018-01-01 2262-04-11  
2    25.0  2018-01-01 2262-04-11  
3     NaN  2018-01-01 2018-12-31  
4     NaN  2018-01-01 2018-11-30  
5     NaN  2018-01-01 2019-02-28  

[6 rows x 22 columns]

答案 28 :(得分:0)

另一个贡献是下面的示例,如果不存在,则会添加该列。

    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

希望有帮助。 西蒙妮(Simone)

答案 29 :(得分:0)

如果该列不存在,请执行以下操作:

> node build.js || nodejs build.js

  CXX(target) Release/obj.target/fibers/src/fibers.o
../src/fibers.cc:68:2: error: no template named 'Handle'
        Handle<String> NewLatin1String(Isolate* isolate, const char* string) {
        ^
../src/fibers.cc:69:10: error: no viable conversion from returned value of type 'Local<v8::String>' to function return type 'int'
                return String::NewFromOneByte(isolate, (const uint8_t*)string, NewStringType::kNormal).ToLocalChecked();
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/fibers.cc:72:2: error: no template named 'Handle'
        Handle<String> NewLatin1Symbol(Isolate* isolate, const char* string) {
        ^
../src/fibers.cc:73:10: error: no viable conversion from returned value of type 'Local<v8::String>' to function return type 'int'
                return String::NewFromOneByte(isolate, (const uint8_t*)string, NewStringType::kNormal).ToLocalChecked();
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/fibers.cc:94:2: error: no template named 'Handle'
        Handle<Object> NewInstance(Isolate* isolate, Local<Function> fn, int argc, Local<Value> argv[]) {
        ^
../src/fibers.cc:95:10: error: no viable conversion from returned value of type 'Local<v8::Object>' to function return type 'int'
                return fn->NewInstance(isolate->GetCurrentContext(), argc, argv).ToLocalChecked();
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/fibers.cc:104:2: error: no template named 'Handle'
        Handle<Number> ToNumber(Local<Value> value) {
        ^
../src/fibers.cc:105:10: error: no viable conversion from returned value of type 'Local<v8::Number>' to function return type 'int'
                return value->ToNumber(Isolate::GetCurrent()->GetCurrentContext()).ToLocalChecked();
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/fibers.cc:114:50: error: no template named 'Handle'
        Local<Value> GetStackTrace(TryCatch* try_catch, Handle<Context> context) {
                                                        ^
../src/fibers.cc:127:39: error: no template named 'Handle'
        void fixStackLimit(Isolate* isolate, Handle<Context> context) {
                                             ^
../src/fibers.cc:149:58: error: no template named 'Handle'
        void Reset(Isolate* isolate, Persistent<T>& persistent, Handle<T> handle) {
                                                                ^
../src/fibers.cc:162:7: error: variable has incomplete type 'void'
        void SetInternalPointer(Handle<T> handle, int index, void* val) {
             ^
../src/fibers.cc:162:26: error: use of undeclared identifier 'Handle'
        void SetInternalPointer(Handle<T> handle, int index, void* val) {
                                ^
../src/fibers.cc:162:33: error: 'T' does not refer to a value
        void SetInternalPointer(Handle<T> handle, int index, void* val) {
                                       ^
../src/fibers.cc:161:18: note: declared here
        template <class T>
                        ^
../src/fibers.cc:162:36: error: use of undeclared identifier 'handle'
        void SetInternalPointer(Handle<T> handle, int index, void* val) {
                                          ^
../src/fibers.cc:162:48: error: expected '(' for function-style cast or type construction
        void SetInternalPointer(Handle<T> handle, int index, void* val) {
                                                  ~~~ ^
../src/fibers.cc:162:59: error: expected '(' for function-style cast or type construction
        void SetInternalPointer(Handle<T> handle, int index, void* val) {
                                                             ~~~~^
../src/fibers.cc:162:61: error: use of undeclared identifier 'val'
        void SetInternalPointer(Handle<T> handle, int index, void* val) {
                                                                   ^
../src/fibers.cc:162:65: error: expected ';' at end of declaration
        void SetInternalPointer(Handle<T> handle, int index, void* val) {
                                                                       ^
                                                                       ;
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
make: *** [Release/obj.target/fibers/src/fibers.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/XXX/.nvm/versions/node/v13.0.1/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (events.js:210:5)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12)
gyp ERR! System Darwin 19.0.0
gyp ERR! command "/Users/XXX/.nvm/versions/node/v13.0.1/bin/node" "/Users/XXX/.nvm/versions/node/v13.0.1/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--release"
gyp ERR! cwd /Users/XXX/Documents/APPNAME/APP-mobile-integration-test/node_modules/wdio-sync/node_modules/fibers
gyp ERR! node -v v13.0.1
gyp ERR! node-gyp -v v5.0.5
gyp ERR! not ok
node-gyp exited with code: 1
Please make sure you are using a supported platform and node version. If you
would like to compile fibers on this machine please make sure you have setup your
build environment--
Windows + OS X instructions here: https://github.com/nodejs/node-gyp
Ubuntu users please run: `sudo apt-get install g++ build-essential`
RHEL users please run: `yum install gcc-c++` and `yum groupinstall 'Development Tools'`
Alpine users please run: `sudo apk add python make g++`
sh: nodejs: command not found
npm WARN APP-mobile-integration-test@1.0.0 No description
npm WARN APP-mobile-integration-test@1.0.0 No repository field.

npm ERR! code ELIFECYCLE
npm ERR! syscall spawn
npm ERR! file sh
npm ERR! errno ENOENT
npm ERR! fibers@3.1.1 install: `node build.js || nodejs build.js`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the fibers@3.1.1 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/XXX/.npm/_logs/2019-11-01T11_40_02_099Z-debug.log```

如果列已存在,请执行以下操作:

import pdfkit as pk

options = {
    'header-center': 'Header',
    'header-html': '<img src="logo.png" />',
}

pk.from_file('indexref.html',
             'wkhtml2pdf doc test.pdf', options=options)

答案 30 :(得分:-1)

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

这应该是相对容易的方法,并且可以直接解决此问题。对于类似的情况,我已经多次使用了。毫无疑问,它就像一种魅力。