在PL/SQL中将列添加到现有表之前,如何检查列是否存在?

在PL/SQL中将列添加到现有表之前,如何检查列是否存在?,sql,oracle,plsql,Sql,Oracle,Plsql,在为oracle db向表中添加列之前,如何添加一个简单的检查?我已经包含了用于添加列的SQL ALTER TABLE db.tablename ADD columnname NVARCHAR2(30); 通常,我建议尝试使用ANSI-92标准元表来实现类似的功能,但现在我发现Oracle不支持它 -- this works against most any other database SELECT * FROM INFORMATION_SCHEMA.COLUMNS

在为oracle db向表中添加列之前,如何添加一个简单的检查?我已经包含了用于添加列的SQL

ALTER TABLE db.tablename 
  ADD columnname NVARCHAR2(30);

通常,我建议尝试使用ANSI-92标准元表来实现类似的功能,但现在我发现Oracle不支持它

-- this works against most any other database
SELECT
    * 
FROM 
    INFORMATION_SCHEMA.COLUMNS C 
    INNER JOIN 
        INFORMATION_SCHEMA.TABLES T 
        ON T.TABLE_NAME = C.TABLE_NAME 
WHERE 
    C.COLUMN_NAME = 'columnname'
    AND T.TABLE_NAME = 'tablename'
相反,你需要做一些事情,比如

-- Oracle specific table/column query
SELECT
    * 
FROM
    ALL_TAB_COLUMNS 
WHERE
    TABLE_NAME = 'tablename'
    AND COLUMN_NAME = 'columnname'

很抱歉,我没有Oracle实例来验证上述内容。如果不起作用,请告诉我,我将删除此帖子。

可以使用以下视图之一访问Oracle数据库中有关列的所有元数据

--对于用户拥有的所有表

--对于用户可访问的所有表

--用于数据库中的所有表

因此,如果您在SCOTT.EMP表中查找像ADD_TMS这样的列,并且仅当该列不存在时才添加该列,那么PL/SQL代码将如下所示

DECLARE
  v_column_exists number := 0;  
BEGIN
  Select count(*) into v_column_exists
    from user_tab_cols
    where upper(column_name) = 'ADD_TMS'
      and upper(table_name) = 'EMP';
      --and owner = 'SCOTT --*might be required if you are using all/dba views

  if (v_column_exists = 0) then
      execute immediate 'alter table emp add (ADD_TMS date)';
  end if;
end;
/
如果计划将其作为脚本运行(不是过程的一部分),最简单的方法是在脚本中包含alter命令,并在脚本末尾查看错误,假设脚本没有Begin end

如果您有file1.sql

alter table t1 add col1 date;
alter table t1 add col2 date;
alter table t1 add col3 date;

如果存在col2,当脚本运行时,其他两列将添加到表中,并且日志将显示错误,表示“col2”已经存在,因此您应该可以。或者,您可以忽略错误:

declare
    column_exists exception;
    pragma exception_init (column_exists , -01430);
begin
    execute immediate 'ALTER TABLE db.tablename ADD columnname NVARCHAR2(30)';
    exception when column_exists then null;
end;
/
检查列是否存在

select column_name as found
from user_tab_cols
where table_name = '__TABLE_NAME__'
and column_name = '__COLUMN_NAME__'

或者尝试并捕获例外情况如果查询
所有选项卡列
数据字典视图,您希望在
所有者
列上包含一个谓词,以防同一个表存在于多个架构中。如果您知道您只对当前用户架构中的表感兴趣,那么您应该使用
user\u TAB\u COLUMNS
视图。Errrr在第一个代码片段中,您是否打算写“COLUMN\u NAME”(而不是“COLLATION\u NAME”)。感谢catch@xDisruptor我现在已经更正了它nice&clean。谢谢好极了!这也可以用于表_exists吗?不幸的是,没有“表_exists”。@grokster要检查表是否存在,只需使用代码-955而不是-01430即可,非常好地避免了讨厌的maven flywayerrors@Mesa非常正确
列\u name
表\u name
中的比较字符串始终需要大写(这就是@mastaBlasta写评论的原因)即使你用不同的大小写创建它们。
创建表foo(bar-number);
将导致
table_-name=foo
column_-name='bar'
@bugybunny,除非列和表名实际上是用小写字母创建的。
创建表“foo”(“bar”-number)
。请注意,这意味着您可以有名为
FOO
FOO
FOO
的表。因此,groksters下面的解决方案在imo上解决问题的效果更好。这个答案只是复制了其他答案中给出的建议,没有添加任何内容。