快速确定ORACLE表中是否存在字段的方法

时间:2010-02-16 21:00:40

标签: sql oracle exists

我正在寻找一个快速的sql语句来确定表中是否存在字段。

实际上我正在使用这句话

Select 1 
   from dual
   where exists (select 1 
                   from all_tab_columns 
                  where table_name = 'MYTABLE' 
                    and column_name = 'MYCOLUMN')

我认为必须有一种最快的方法来确定ORACLE中是否存在列。

更新

我正在优化一个更大的软件系统,该系统会多次调用此查询,我无法修改源代码;(只有我可以修改存储在外部文件中的查询。

表all_tab_columns有超过一百万条记录。

6 个答案:

答案 0 :(得分:9)

all_tab_columns的主键是owner, table_name, column_name,因此寻找特定的所有者会更快(或使用user_tab_columns)。

答案 1 :(得分:2)

我建议阅读这篇AskTom文章。它解释了最快的检查方法是不要检查。

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:698008000346356376

答案 2 :(得分:1)

查询Oracle数据字典 - 正如您的示例所做的那样,可能是最快的方式。

数据字典缓存在内存中,应该能够很快地满足查询。如果您知道表的实际模式所有者,则可能会获得稍快的结果 - 这样您就不会因为搜索所有模式而产生成本。

答案 3 :(得分:1)

此查询就足够了:

 SELECT null
  FROM user_tab_columns
 WHERE table_name = 'MYTABLE' and column_name = 'MYCOLUMN'

唯一最快的方法是直接从内部表中查询不推荐的方式,并且需要对sys对象进行授权:

select null
from sys.col$ c
   , sys.obj$ o
   , sys.obj$ ot
where o.name = 'MYTABLE'
  and c.name = 'MYCOLUMN'
  and o.obj# = c.obj#
  and o.owner# = userenv('SCHEMAID')
  and ot.type#(+) = 13
  and (o.type# in (3, 4)                                    
       or
       (o.type# = 2 
        and
        not exists (select null
                      from sys.tab$ t
                     where t.obj# = o.obj#
                       and (bitand(t.property, 512) = 512 or
                            bitand(t.property, 8192) = 8192))))

此查询取自USER_TAB_COLUMNS定义,可以更改不同版本(我的情况下为10gR2)。在此查询中,我删除了对您未请求的信息的引用。

无论如何,你为什么要查看这个?

答案 4 :(得分:0)

此SQL查询将提供具有列' NAVIGATION_ID'的所有表的名称。对于用户' DSGIDEV'

从all_tab_cols中选择*,其中column_name =' NAVIGATION_ID'和所有者=' DSGIDEV'

因此,请使用您要搜索的列更改列名称,并使用您的所有者ID名称更改所有者。

答案 5 :(得分:0)

Ez,最快的方法就是创建这样的函数:

  Create function exist(v_table in varchar2, v_col in  varchar2) 
 Return integer is
 Res integer:= 0;
 Begin
   Begin
      Execute immediate 'select ' || v_col || ' from '|| v_table;         
      Res:=1;
      Exception when other then null;
   End;
Return (res);
End;