这是来自Cognos报告,它有一个交互式的多值提示(P_prompt_param)。
查询是使用Tabular 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:无效数字
这在Oracle 10.2.0.4上。
我一直在使用SQL来查看我是否可以在“工作”环境中重现它,如果我想象在没有选择输入的情况下如何评估#promptmany#宏(defaultText值为'NO INPUT “)。
像这样的查询将获得ORA-01722
select * from mytable where ( someval in ('NO INPUT'));
此查询的位置,更像是我报告中的上述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
上答案 0 :(得分:1)
优化器可以按其选择的顺序自由地评估谓词。因此,可以在someval in ('NO INPUT')
谓词之前评估'NO INPUT' in ('NO INPUT')
谓词,在这种情况下您将收到错误。
如果someval
是NUMBER
,它应该与数字进行比较,而不是字符串,所以我希望提示应该被定义为数字并且“无输入” “选项应该是无效的数字,即-1。或者,您可以在进行比较之前将someval
转换为字符串
to_char( someval ) IN ('NO INPUT')
将是不会引发运行时错误的有效语法。但是,如果您依赖于someval
上的索引,则添加TO_CHAR
将阻止使用该索引。您可以通过创建基于函数的索引来解决该问题
CREATE INDEX fbi_tbl_someval
ON mytable( to_char( someval ) );
但是,当表中的数据发生更改,两个索引消耗磁盘空间等时,您可能需要维护两个不同的索引。