【问题标题】:Select a column that potentially doesn't exist in Oracle dictionary views选择 Oracle 字典视图中可能不存在的列
【发布时间】:2012-05-01 20:56:08
【问题描述】:

我想在SYS.ALL_ARGUMENTS 上创建一个向后兼容的查询。在 Oracle 11g 中,添加了有用的 ALL_ARGUMENTS.DEFAULTED 列。现在,如果我对 Oracle 10g 运行此查询:

SELECT defaulted FROM all_arguments

当然,我得到一个错误。

ORA-00904: "SYS"."ALL_ARGUMENTS"."DEFAULTED": 标识符无效

我想做的是:

SELECT CASE WHEN column_exists("defaulted") 
            THEN defaulted 
            ELSE 'N'
       END
FROM all_arguments

甚至更好

SELECT evaluate_column_on_current_row(column_name           => "defaulted", 
                                      default_if_not_exists => 'N')
FROM all_arguments

有没有什么方法可以在单个 SQL 查询中做到这一点,而无需使用 PL/SQL?或者我应该像这样先检查 Oracle 版本:

SELECT count(*) 
FROM all_tab_cols
WHERE owner = 'SYS'
AND table_name = 'ALL_ARGUMENTS'
AND column_name = 'DEFAULTED'

【问题讨论】:

  • @Arion: ORA-00904... 查看更新后的问题

标签: sql oracle compatibility information-schema


【解决方案1】:

引用不存在的列的查询无法生成有效的计划。

您需要选择一种方法,其中提交的查询始终有效。无论是动态生成/执行它们,还是其他一些方法。

但是如果你提交一个要解析的查询,并且它在一个存在的表中包含一个不存在的字段,那么解析器就会把它扔给你。

【讨论】:

  • 是的,但我认为可能有一些系统函数来评估给定投影中当前行的表达式。显然,这不是执行计划生成的最佳选择,但我不明白为什么这在原则上是不可能的......我为这个问题添加了一个更好的例子,具有完全动态的列名评估
  • @LukasEder - 简单地说,因为 SQL 已编译。如果您想要一个间接级别,即在运行时查找字段名称,则解决方案动态SQL。这件事情是由很多原因导致的;最简单的一种是,当提交查询以进行解析和编译时,会检查各种统计信息和其他详细信息(索引、约束、选择性等)以形成计划。然后为 that 查询修复该计划。如果你提交一个稍微不同的查询,你就会得到一个新的计划。这就是 SQL 的工作方式。对于您的初始示例,动态 SQL 似乎非常适合我。
猜你喜欢
  • 2016-10-24
  • 2018-09-01
  • 2017-10-02
  • 2013-09-14
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
  • 2012-03-23
  • 1970-01-01
相关资源
最近更新 更多