Tengo un código Java que recorta una cadena UTF-8 al tamaño de mi columna Oracle (11.2.0.4.0) que termina arrojando un error porque Java y Oracle ven la cadena como longitudes de bytes diferentes. Verifiqué que mi NLS_CHARACTERSET
parámetro en Oracle es 'UTF8'.
Escribí una prueba que ilustra mi problema a continuación usando el emoji chipmunk unicode (🐿️)
public void test() throws UnsupportedEncodingException, SQLException {
String squirrel = "\uD83D\uDC3F\uFE0F";
int squirrelByteLength = squirrel.getBytes("UTF-8").length; //this is 7
Connection connection = dataSource.getConnection();
connection.prepareStatement("drop table temp").execute();
connection.prepareStatement("create table temp (foo varchar2(" + String.valueOf(squirrelByteLength) + "))").execute();
PreparedStatement statement = connection.prepareStatement("insert into temp (foo) values (?)");
statement.setString(1, squirrel);
statement.executeUpdate();
}
Esto falla en la última línea de la prueba con el siguiente mensaje:
ORA-12899: valor demasiado grande para la columna
"MISQUEMA". "TEMP". "FOO" (real: 9, máximo: 7)
El ajuste de NLS_LENGTH_SEMANTICS
es BYTE
. Desafortunadamente, no puedo cambiar esto, ya que es un sistema heredado. No me interesa aumentar el tamaño de la columna, solo poder predecir de manera confiable el tamaño de Oracle de una cadena.