Insertar caracteres coreanos a través de JDBC a través del procedimiento almacenado MYSQL dando error

Creo que estoy usando los parámetros queryString correctos para la conexión jdbc

jdbc:mysql://localhost:3306/databasename?useUnicode=true&characterEncoding=utf8&noAccessToProcedureBodies=true

Mi base de datos es configurado correctamente para admitir utf-8 (variables de caracteres predeterminadas).

character_set_client utf8
character_set_connection utf8
character_set_database latin1
character_set_filesystem binary
character_set_results utf8
character_set_server latin1
character_set_system utf8

Mi sproc define cada parámetro como utf8 cuando sea necesario

IN _shortDesc MEDIUMTEXT character set utf8,

LLAMAR al sproc a través de MySQLWorkbench funciona como se esperaba. Sin embargo, llamarlo desde Java da como resultado una excepción.

java.sql.SQLException: Incorrect string value: '\xAC\xED\x00\x05t\x00...' for column '_shortDesc'

Curiosamente, cambiar la definición de sproc para campos relevantes a utf16 or ucs2 da como resultado ninguna excepción, sino caracteres coreanos incorrectos en la tabla.

También intenté usar una matriz de bytes al construir los parámetros sql en Java

getBytes(Charset.forName("UTF-8"))

Pero la excepción todavía se lanza.

¿Cuál es la forma correcta de configurar esto para pasar correctamente los caracteres CJK a través de Java a MySQL a través de un procedimiento almacenado?

EDITAR estoy usando SimpleJdbcCall desde el marco de primavera

DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://server/test?characterEncoding=utf8");
ds.setUsername("user");  
ds.setPassword("pass");

// must explicitly declare params
SimpleJdbcCall jdbc = new SimpleJdbcCall(ds)
    .withProcedureName("sp_gms_addGameTranslationsTest");

SqlParameterSource in = new MapSqlParameterSource()
    .addValue("_test", "그러나 사디라");

jdbc.execute(in);

preguntado el 12 de junio de 12 a las 16:06

¿Podría pegar la cadena (o la parte ofensiva) que está tratando de insertar? no hace falta decir que \xAC\xED no es UTF-8 válido, y esos cero bytes también se ven extraños. -

Cualquier texto en coreano, chino o japonés fallará: aquí hay un fragmento que funciona bien cuando se llama directamente al sproc (por lo que no es el texto el que está mal, debe ser el controlador jdbc). 겠겠지만 -

No se puede reproducir el problema con MySQL 5.5 y Connector/J 5.1.20: esto funciona como se esperaba gist.github.com/2918685 -

Podría ser solo una versión del problema del controlador. Estoy usando el paquete springs jdbc. Probé tu código usando 5.1.20 y funcionó bien. -

1 Respuestas

El problema principal fue que estoy usando springframework SimpleJdbcCall para ejecutar el procedimiento almacenado. Eso simplifica la configuración mediante el uso de metadatos de bases de datos para resolver las cosas por usted. Al declarar explícitamente mis parámetros de entrada cuando uso ese objeto, la llamada funciona bien.

p.ej

DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://server/test?characterEncoding=utf8");
ds.setUsername("user");  
ds.setPassword("pass");

// must explicitly declare params
SimpleJdbcCall jdbc = new SimpleJdbcCall(ds)
    .withProcedureName("sp_gms_addGameTranslationsTest")
    .declareParameters(
        new SqlParameter("_test", Types.VARCHAR)
);

SqlParameterSource in = new MapSqlParameterSource()
    .addValue("_test", "그러나 사디라");

jdbc.execute(in);

Me doy cuenta de que era imposible llegar a esta respuesta a partir de mi pregunta original, por lo que agregué una edición.

Respondido el 13 de junio de 12 a las 14:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.