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

Pra*_*abu 54 sql oracle plsql

在为oracle db的表添加列之前,如何添加简单检查?我已经包含了我用来添加列的SQL.

ALTER TABLE db.tablename 
  ADD columnname NVARCHAR2(30);
Run Code Online (Sandbox Code Playgroud)

Raj*_*thi 91

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

user_tab_cols ; - 对于用户拥有的所有表

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

dba_tab_cols ; - 对于数据库中的所有表.

因此,如果您正在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;
/
Run Code Online (Sandbox Code Playgroud)

如果您计划将此作为脚本运行(不是过程的一部分),最简单的方法是在脚本中包含alter命令并查看脚本末尾的错误,假设您没有Begin-End剧本..

如果你有file1.sql

alter table t1 add col1 date;
alter table t1 add col2 date;
alter table t1 add col3 date;
Run Code Online (Sandbox Code Playgroud)

并且存在col2,当脚本运行时,其他两列将被添加到表中,日志将显示错误"col2"已经存在,所以你应该没问题.


gro*_*ter 27

或者,您可以忽略错误:

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;
/
Run Code Online (Sandbox Code Playgroud)

  • @grokster要检查表是否存在,只需使用代码-955而不是-01430 (2认同)

bil*_*nkc 10

通常情况下,我建议尝试使用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'
Run Code Online (Sandbox Code Playgroud)

相反,看起来你需要做类似的事情

-- Oracle specific table/column query
SELECT
    * 
FROM
    ALL_TAB_COLUMNS 
WHERE
    TABLE_NAME = 'tablename'
    AND COLUMN_NAME = 'columnname'
Run Code Online (Sandbox Code Playgroud)

我很抱歉,我没有Oracle实例来验证上述情况.如果它不起作用,请告诉我,我将删除此帖.

  • 如果查询`ALL_TAB_COLUMNS`数据字典视图,则需要在`OWNER`列中包含谓词,以防多个模式中存在相同的表.如果您知道自己只对当前用户架构中的表感兴趣,则应使用"USER_TAB_COLUMNS"视图. (8认同)
  • 或尝试并捕获异常 (3认同)