【问题标题】:Fast way to determine if an field exist in a ORACLE table确定 ORACLE 表中是否存在字段的快速方法
【发布时间】:2011-01-17 14:12:43
【问题描述】:

我正在寻找一个快速的 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 有超过一百万条记录。

【问题讨论】:

  • 如果这个查询的性能是一个问题,听起来你的数据模型有问题。你能解释一下为什么需要这个吗?
  • 为什么需要快速查询?阅读表格描述输出有什么问题?或者为什么你不能阅读创建模型的 DDL?

标签: sql oracle exists


【解决方案1】:

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;

【讨论】:

    【解决方案2】:

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

    select * from all_tab_cols where column_name = 'NAVIGATION_ID' and owner = 'DSGIDEV'

    因此,将列名称更改为您要搜索的列,并将所有者更改为您的所有者 ID 名称。

    【讨论】:

      【解决方案3】:

      这个查询就够了:

       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】:

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

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

        【讨论】:

          【解决方案5】:

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

          数据字典缓存在内存中,应该能够很快满足查询。如果您知道表的实际架构所有者,您可能能够获得稍微快一点的结果 - 这样您就不会产生针对所有架构进行搜索的成本。

          【讨论】:

            【解决方案6】:

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

            【讨论】:

            • +1 用于添加所有者。如果没有表所有者,结果将毫无用处。鉴于此,我会看到用 SELECT 1 FROM DUAL 替换它会产生什么效果。如果您想要一个有用的答案,可能需要先检查 USER_TAB_COLUMNS,然后检查 ALL_SYNONYMS 以获取特定同义词或 PUBLIC 同义词,然后与表所有者一起转到 ALL_TAB_COLUMNS。注意:你可以有同义词指向同义词等。所以正确的答案会更慢。
            猜你喜欢
            • 2010-10-10
            • 2013-08-09
            • 1970-01-01
            • 1970-01-01
            • 2010-11-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-07
            相关资源
            最近更新 更多