This is from a Cognos report, it has an interactive, multi-valued prompt (P_prompt_param).
The query is written with Tabular SQL. To make it an optional filter on the column (someval) the report writer wrote it like this in the query’s where clause:
(
'NO INPUT' IN (#promptmany('P_prompt_param', 'String', sq('NO INPUT'))#)
or
table.somval IN (#promptmany('P_prompt_param', 'String', sq('NO INPUT'))#)
)
In this case table.somval is of type NUMBER. If you don’t select a value in the prompt on the input page. The report will return, on 4 environments with identical DB schemas, but there is one environment where this will not work.
Instead in the one outlier it results in ORA-01722: invalid number
This on Oracle 10.2.0.4.
I’ve been playing around in SQL to see if I can reproduce it on a “working” environment, if I imagine how the #promptmany# macro would be evaluated when there is no input selected (defaultText value of ‘NO INPUT’).
A query like this will get ORA-01722
select * from mytable where ( someval in ('NO INPUT'));
Where as this query, more like the above where clause in my report, will not
select * from mytable where ('NO INPUT' in ('NO INPUT') or someval in ('NO INPUT'));
Is there any way that the OR expressions could be both evaluated even after the first one returns true? Or is it possible that the order of evaluation can “switch”?
is there some setting in Cognos or Oracle that might determine the order or if both expressions could be evaluated? might it depend on the optimizer somehow?
This is on Cognos ReportNet 1.1, Oracle 10g
The optimizer is free to evaluate predicates in whatever order it chooses. So it is free to evaluate the
someval in ('NO INPUT')predicate before the'NO INPUT' in ('NO INPUT')predicate in which case you’ll get an error.If
somevalis aNUMBER, it ought to be compared with a number, not a string, so I would expect that the prompt ought to be defined as a number and that the “No Input” option ought to be a number that isn’t valid, i.e. -1. Alternately, you could convertsomevalto a string before doing the comparisonwill be valid syntax that won’t throw a runtime error. However, if you are relying on an index on
someval, adding theTO_CHARwill prevent that index from being used. You can work around that problem by creating a function-based indexBut then you have potentially two different indexes to maintain when data changes in the tables, two indexes consuming disk space, etc.