4

マスター テーブル (以降、SURVEY と呼びます) と詳細テーブル (以降、ANSWERS と呼びます) があります。当然のことながら、ANSWERS には SURVEY の質問に対する回答があります。ANSWERS には、TEXT という名前の VARCHAR2 列があります。一部の ANSWERS.TEXT 値は実際にはテキストですが、一部は実際には数値です。幸いなことに、どの行にテキストが含まれ、どの行に数値がテキストとして含まれているかは常にわかっています。

これがその通りです。これを変更することはできません。

昔、特定の ANSWERS 行が保存されたとき、それらの TEXT 値は厳選され、適切に型指定された列の SURVEY テーブルに入れられました。単純な 1 つのテーブルを選択すると、SURVEY と特別な値がフェッチされます。

しかし、新しいアプリケーションの追加に伴い、特別な列を削除しました。代わりに、適切な ANSWERS 行の TEXT 値を取得する必要があります。

古い単純な select ステートメントをシミュレートするクエリを作成しました。それはうまく機能します...ほとんど。

ここにスニペットがあります:

select survey.*, 
       j2.overall_score
  from survey,
       (select to_number(trim(ANSWER.text)) overall_score, 
               survey.id survey_id 
          from ANSWER, 
               [edited - more SQL that gets the 'score' row from ANSWERS]) j2      
 where
   survey.id=j2.survey_id
   and overall_score > 70    

j2 に注意してください。実際のクエリには、j1 から j6 までの 6 つの列があります。クエリを実行すると、古いクエリと同じように見えます。マスター/ディテールから実際に組み立てられているとは言えません。それは安心です!

しかし、私の問題は、「overall_score > 70」というフレーズが「1722 無効な数値」エラーを引き起こすことです。オラクルは、私がこのフレーズを含めないときは満足しています。そのため、すべての出力は j2 の to_number() 関数を通過し、見栄えがよくなります。しかし、条件を追加すると失敗します。

where 句の「overall_score」部分は、Web ページから入力された検索基準に基づいて動的に追加されています。

オラクルに、私が何をしているのか本当に知っていると伝えるためのフーが必要です。実行してください。数値以外のデータがある場合は、j2 の to_number() を失敗させます。涼しい。しかし、それ以外の場合は、それを実行してください。

賢い言葉はありますか?私は請負業者であり、時間が迫っています。これは新しい要件です:-/

4

2 に答える 2

10

オプティマイザーはおそらくインライン ビューを残りのクエリとマージしていると思います。つまり、overall_score > 70残りのビューの述語と一致しない行に対して条件が評価され、数値を含まない行にヒットする可能性があります。でtext

それが起こっている場合は、クエリの最初の行にヒントを追加することでそれを防ぐことができるはずです:

select /*+ NO_MERGE(j2) */ ...

または、述語をビューにプッシュすることもできます。その場合、NO_PUSH_PRED ヒントが必要になります。クエリの実行計画を生成できる場合は、おそらく正確な問題が何であるかがわかります。

于 2010-09-16T15:50:58.587 に答える
3

「1722 無効な番号」例外を内部的にキャッチし、代わりに 0 を返す特別なバージョンの to_number を作成しました。th sql で to_number をこの新しい関数に置き換えると、この問題が解消されました。

于 2010-09-16T18:16:44.197 に答える