Oracle 10 e JDBC: come fare in modo che CHAR ignori gli spazi finali al confronto?

StackOverflow https://stackoverflow.com/questions/603245

  •  03-07-2019
  •  | 
  •  

Domanda

Ho una query che ha

  

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

Il campo prt_status è definito come CHAR (5) però. Quindi è sempre imbottito di spazi. La query non corrisponde a nulla come risultato. Per far funzionare questa query devo farlo

  

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

che funziona.

È fastidioso.

Allo stesso tempo, un paio di client DBMS pure-java (Oracle SQLDeveloper e AquaStudio) NON ho un problema con la prima query, restituiscono il risultato corretto. Anche TOAD non ha problemi.

Presumo che abbiano semplicemente messo la connessione in una modalità di compatibilità (ad es. ANSI), quindi Oracle sa che CHAR (5) dovrebbe essere confrontato senza rispetto per i caratteri finali.

Come posso farlo con gli oggetti Connessione che ottengo nella mia applicazione?

AGGIORNAMENTO Non riesco a modificare lo schema del database.

SOLUZIONE Era davvero il modo in cui Oracle confronta i campi con i parametri passati.

Al termine del bind, la stringa viene passata tramite PreparedStatement.setString (), che imposta il tipo su VARCHAR, e quindi Oracle utilizza il confronto non imbottito - e non riesce.

Ho provato a usare setObject (n, str, Types.CHAR). Non riesce. La decompilazione mostra che Oracle ignora CHAR e lo passa nuovamente come VARCHAR.

La variante che finalmente funziona è

setObject(n,str,OracleTypes.FIXED_CHAR);

Rende il codice non portatile però.

I client UI hanno successo per un motivo diverso: usano letterali di caratteri, non vincolanti. Quando digito PRT_STATUS = 'ONT', 'ONT' è un valore letterale e, in quanto tale, confrontato usando il modo imbottito.

È stato utile?

Soluzione

Nota che Oracle confronta CHAR utilizzando la semantica di confronto con riempimento vuoto.

Da Regole di confronto dei tipi di dati ,

  

Oracle utilizza un confronto vuoto   semantica solo quando entrambi i valori in   il confronto è una delle espressioni di   tipo di dati CHAR, NCHAR, valori letterali di testo,   o valori restituiti dall'UTENTE   la funzione.

Nel tuo esempio, 'ONT' viene passato come parametro bind, oppure è incorporato nella query testualmente, come hai illustrato? Se un parametro bind, assicurati che sia associato come tipo CHAR . Altrimenti, verifica la versione della libreria client utilizzata, poiché le versioni davvero vecchie di Oracle (ad es. V6) avranno una semantica di confronto diversa per CHAR .

Altri suggerimenti

Se non è possibile modificare la tabella del database, è possibile modificare la query.

Alcune alternative per RTRIM:

  

.. DOVE PRT_STATUS come 'ONT%' ...

     

.. WHERE PRT_STATUS = 'ONT' ... - 2 spazi bianchi dietro T

     

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

Vorrei cambiare la colonna CHAR (5) in varchar2 (5) in db.

Puoi utilizzare l'operazione cast to char nella tua query:

... WHERE PRT_STATUS=cast('ONT' as char(5))

O in un modo JDBC più generico:

... WHERE PRT_STATUS=cast(? as char(5))

E poi nel tuo codice JDBC usa statement.setString (1, " ONT ");

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top