2

这来自 Cognos 报表,它具有交互式多值提示 (P_prompt_param)。

该查询是使用表格 SQL 编写的。为了使它成为列(someval)上的可选过滤器,报告编写者在查询的 where 子句中这样写:

( 
       'NO INPUT' IN (#promptmany('P_prompt_param', 'String', sq('NO INPUT'))#)
       or
       table.somval IN (#promptmany('P_prompt_param', 'String', sq('NO INPUT'))#)
      )

在这种情况下,table.somval 的类型为 NUMBER。如果您没有在输入页面的提示中选择值。该报告将在 4 个具有相同数据库架构的环境中返回,但有一个环境无法正常工作。

相反,在一个异常值中,它会导致 ORA-01722: invalid number

这在 Oracle 10.2.0.4 上。

我一直在玩 SQL,看看我是否可以在“工作”环境中重现它,如果我想象在没有选择输入时如何评估 #promptmany# 宏(defaultText 值为 'NO INPUT')。

像这样的查询会得到 ORA-01722

select * from mytable where ( someval in ('NO INPUT'));

where 作为这个查询,更像是我报告中的上述 where 子句,不会

select * from mytable where ('NO INPUT' in ('NO INPUT') or someval in ('NO INPUT'));

即使在第一个返回 true 之后,有什么方法可以同时评估 OR 表达式?还是评估顺序可以“切换”?

Cognos 或 Oracle 中是否有一些设置可以确定顺序,或者是否可以评估两个表达式?它可能以某种方式依赖于优化器吗?

这是在 Cognos ReportNet 1.1、Oracle 10g 上

4

1 回答 1

1

优化器可以自由地以它选择的任何顺序评估谓词。所以在someval in ('NO INPUT')谓词之前评估谓词是自由的,'NO INPUT' in ('NO INPUT')在这种情况下你会得到一个错误。

如果someval是 a NUMBER,它应该与一个数字而不是字符串进行比较,所以我希望提示应该被定义为一个数字,并且“No Input”选项应该是一个无效的数字,即-1。或者,您可以someval在进行比较之前转换为字符串

to_char( someval ) IN ('NO INPUT')

将是不会引发运行时错误的有效语法。但是,如果您依赖 上的索引someval,添加TO_CHAR将阻止使用该索引。您可以通过创建基于函数的索引来解决该问题

CREATE INDEX fbi_tbl_someval
    ON mytable( to_char( someval ) );

但是当表中的数据发生变化时,您可能需要维护两个不同的索引,两个索引消耗磁盘空间等。

于 2011-12-02T19:26:27.340 回答