8

私は持っているクエリを持っています

... WHERE PRT_STATUS='ONT' ...

ただし、prt_status フィールドは CHAR(5) として定義されています。そのため、常にスペースが埋め込まれます。結果として、クエリは何も一致しません。このクエリを機能させるには、私がしなければならない

... WHERE rtrim(PRT_STATUS)='ONT'

これは機能します。

うざい。

同時に、いくつかの純粋な Java DBMS クライアント (Oracle SQLDeveloper と AquaStudio) は、最初のクエリで問題なく、正しい結果を返します。TOADも問題ありません。

単に接続を何らかの互換モード (ANSI など) に設定しただけだと思います。そのため、オラクルは CHAR(5) が末尾の文字を考慮せずに比較されることを期待していることを認識しています。

アプリケーションで取得した Connection オブジェクトを使用してそれを行うにはどうすればよいですか?

UPDATEデータベース スキーマを変更できません。

解決策これは実際、Oracle がフィールドを渡されたパラメーターと比較する方法でした。

バインドが完了すると、タイプを VARCHAR に設定する PreparedStatement.setString() を介して文字列が渡されるため、Oracle はパディングなしの比較を使用し、失敗します。

setObject(n,str,Types.CHAR) を使用しようとしました。失敗します。逆コンパイルは、Oracle が CHAR を無視し、VARCHAR として再び渡すことを示しています。

最終的に機能するバリアントは

setObject(n,str,OracleTypes.FIXED_CHAR);

ただし、コードは移植できません。

UI クライアントは別の理由で成功します。バインディングではなく、文字リテラルを使用します。PRT_STATUS='ONT' と入力すると、'ONT' はリテラルであり、パディングされた方法で比較されます。

4

4 に答える 4

8

Oracleは、空白が埋め込まれた比較セマンティクスを使用して値を比較することに注意してください。CHAR

データ型比較規則から、

Oracle は、比較の両方の値がデータ型 CHAR、NCHAR、テキスト リテラルの式、または USER 関数によって返される値のいずれかである場合にのみ、空白が埋め込まれた比較セマンティクスを使用します。

あなたの例では'ONT'、バインドパラメーターとして渡されますか、それとも、説明したようにテキストでクエリに組み込まれていますか? バインド パラメータの場合は、 type としてバインドされていることを確認してくださいCHAR。それ以外の場合は、使用されているクライアント ライブラリのバージョンを確認してください。Oracle の非常に古いバージョン (v6 など) では、 の比較セマンティクスが異なるためですCHAR

于 2009-03-02T17:55:32.697 に答える
1

データベース テーブルを変更できない場合は、クエリを変更できます。

RTRIM の代替手段:

..「ONT%」のような WHERE PRT_STATUS ...

.. WHERE PRT_STATUS = 'ONT ' ... -- T の後ろに 2 つの空白

.. WHERE PRT_STATUS = rpad('ONT',5,' ') ...

于 2009-03-02T19:19:16.443 に答える
0

データベースで CHAR(5) 列を varchar2(5) に変更します。

于 2009-03-02T17:42:42.400 に答える