Oracle 10 y JDBC: ¿cómo hacer que CHAR ignore los espacios finales en comparación?

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

  •  03-07-2019
  •  | 
  •  

Pregunta

Tengo una consulta que tiene

  

... DONDE PRT_STATUS = 'ONT' ...

El campo prt_status se define como CHAR (5) sin embargo. Por eso siempre se rellena con espacios. La consulta no coincide con nada como el resultado. Para que funcione esta consulta tengo que hacer

  

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

que funciona.

Eso es molesto.

Al mismo tiempo, un par de clientes DBMS que son Java puro (Oracle SQLDeveloper y AquaStudio) NO tengo un problema con la primera consulta, devuelven el resultado correcto. TOAD tampoco tiene ningún problema.

Supongo que simplemente ponen la conexión en algún modo de compatibilidad (por ejemplo, ANSI), por lo que Oracle sabe que se espera que CHAR (5) se compare sin respeto a los caracteres finales.

¿Cómo puedo hacerlo con los objetos de conexión que obtengo en mi aplicación?

ACTUALIZACIÓN No puedo cambiar el esquema de la base de datos.

SOLUCIÓN De hecho, fue la manera en que Oracle compara los campos con los parámetros pasados.

Cuando se realiza la vinculación, la cadena se pasa a través de PreparedStatement.setString (), que establece el tipo en VARCHAR y, por lo tanto, Oracle utiliza comparaciones sin relleno, y falla.

Intenté usar setObject (n, str, Types.CHAR). Falla La descompilación muestra que Oracle ignora CHAR y lo pasa como un VARCHAR nuevamente.

La variante que finalmente funciona es

setObject(n,str,OracleTypes.FIXED_CHAR);

Aunque hace que el código no sea portátil.

Los clientes de IU tienen éxito por una razón diferente: usan literales de caracteres, no vinculantes. Cuando escribo PRT_STATUS = 'ONT', 'ONT' es un literal y, como tal, se compara mediante el uso de una forma acolchada.

¿Fue útil?

Solución

Tenga en cuenta que Oracle compara Valores de CHAR que utilizan semánticas de comparación rellenadas con espacios en blanco.

De Reglas de comparación de tipos de datos ,

  

Oracle usa una comparación en blanco   semántica sólo cuando ambos valores en el   comparación son expresiones de   tipo de datos CHAR, NCHAR, textos literales,   o valores devueltos por el USUARIO   función.

En su ejemplo, ¿se pasa 'ONT' como un parámetro de enlace, o está integrado en la consulta textualmente, como ilustró? Si es un parámetro de enlace, asegúrese de que esté vinculado como tipo CHAR . De lo contrario, verifique la versión de la biblioteca cliente utilizada, ya que las versiones realmente antiguas de Oracle (por ejemplo, v6) tendrán una semántica de comparación diferente para CHAR .

Otros consejos

Si no puede cambiar la tabla de su base de datos, puede modificar su consulta.

Algunas alternativas para RTRIM:

  

.. DONDE PRT_STATUS le gusta 'ONT%' ...

     

.. WHERE PRT_STATUS = 'ONT' ... - 2 espacios en blanco detrás de T

     

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

Cambiaría la columna CHAR (5) a varchar2 (5) en db.

Puede usar la operación de conversión de caracteres a caracteres en su consulta:

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

O de una forma JDBC más genérica:

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

Y luego en su código JDBC, utilice statement.setString (1, " ONT ");

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top