Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Oracle10 and JDBC: how to make CHAR ignore trailing spaces at comparision?

Tags:

char

oracle

jdbc

I have a query that has

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

The prt_status field is defined as CHAR(5) though. So it's always padded with spaces. The query matches nothing as the result. To make this query work I have to do

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

which does work.

That's annoying.

At the same time, a couple of pure-java DBMS clients (Oracle SQLDeveloper and AquaStudio) I have do NOT have a problem with the first query, they return the correct result. TOAD has no problem either.

I presume they simply put the connection into some compatibility mode (e.g. ANSI), so the Oracle knows that CHAR(5) expected to be compared with no respect to trailing characters.

How can I do it with Connection objects I get in my application?

UPDATE I cannot change the database schema.

SOLUTION It was indeed the way Oracle compares fields with passed in parameters.

When bind is done, the string is passed via PreparedStatement.setString(), which sets type to VARCHAR, and thus Oracle uses unpadded comparision -- and fails.

I tried to use setObject(n,str,Types.CHAR). Fails. Decompilation shows that Oracle ignores CHAR and passes it in as a VARCHAR again.

The variant that finally works is

setObject(n,str,OracleTypes.FIXED_CHAR);

It makes the code not portable though.

The UI clients succeed for a different reason -- they use character literals, not binding. When I type PRT_STATUS='ONT', 'ONT' is a literal, and as such compared using padded way.

like image 355
Vladimir Dyuzhev Avatar asked Mar 02 '09 17:03

Vladimir Dyuzhev


People also ask

How to remove trailing spaces from a column in Oracle?

The Oracle TRIM function is used to remove all leading or trailing characters (or both) from a character string. If trim_character or trim_source is a character literal, then it is necessary to enclose it in single quotation marks. When no trim_character is specified, then the default value is a blank space.

How to remove leading spaces in Oracle?

use the trim function removes all specified characters either from the beginning or the ending of a string.

What is white space in Oracle?

Oracle Enterprise Data Quality Online Help Whitespace is defined in EDQ as: Spaces. Non-printable characters, such as carriage returns, line feeds and tabs (and all other ASCII characters 0-31)


2 Answers

Note that Oracle compares CHAR values using blank-padded comparison semantics.

From Datatype Comparison Rules,

Oracle uses blank-padded comparison semantics only when both values in the comparison are either expressions of datatype CHAR, NCHAR, text literals, or values returned by the USER function.

In your example, is 'ONT' passed as a bind parameter, or is it built into the query textually, as you illustrated? If a bind parameter, then make sure that it is bound as type CHAR. Otherwise, verify the client library version used, as really old versions of Oracle (e.g. v6) will have different comparison semantics for CHAR.

like image 116
vladr Avatar answered Sep 23 '22 15:09

vladr


If you cannot change your database table, you can modify your query.

Some alternatives for RTRIM:

.. WHERE PRT_STATUS like 'ONT%' ...

.. WHERE PRT_STATUS = 'ONT ' ... -- 2 white spaces behind T

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

like image 29
Edwin Avatar answered Sep 25 '22 15:09

Edwin