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です。入力ページのプロンプトで値を選択しない場合。レポートは、同一のDBスキーマを持つ4つの環境で返されますが、これが機能しない環境が1つあります。

代わりに、1つの外れ値では、ORA-01722:無効な番号になります。

これはOracle10.2.0.4で。

入力が選択されていない場合(defaultText値が「NOINPUT」)に#promptmany#マクロがどのように評価されるかを想像すると、SQLを試して、「動作中」の環境で再現できるかどうかを確認しています。

このようなクエリは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に、順序を決定する可能性のある設定、または両方の式を評価できる設定はありますか?どういうわけかオプティマイザーに依存するのでしょうか?

これはCognosReportNet1.1、Oracle10gにあります

4

1 に答える 1

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 ) );

ただし、テーブル内のデータが変更されたときに維持する2つの異なるインデックス、ディスク領域を消費する2つのインデックスなどが存在する可能性があります。

于 2011-12-02T19:26:27.340 に答える