Pregunta

En SQL se puede escribir una consulta que busca el nombre de una persona como esta:

SELECT * FROM Person P WHERE P.Name LIKE N'%ike%'

Esta consulta se ejecutaría con caracteres Unicode (suponiendo que la columna Nombre y la base de datos se configuraron para manejar el soporte Unicode).

Tengo una consulta similar en HQL que ejecuta Hibernate (NHibernate). La consulta generada se ve así:

SELECT P FROM SumTotal.TP.Models.Party.Person P join P.Demographics PD WHERE (PD.LastName LIKE '%カタカ%'  )

Desafortunadamente, colocar una 'N' delante del literal en el HQL da como resultado un error. Intenté escapar de los caracteres Unicode en la cadena y todavía no tuve éxito.

La base de datos está aceptando y guardando caracteres unicode de Hibernate. He podido completar con éxito un objeto con una cadena Unicode, guardarlo con Hibernate y verificarlo en la base de datos. Me parece un poco extraño que no pueda usar cadenas unicode en consultas personalizadas (o también supongo que las consultas con nombre).

¿Es este un problema conocido o una limitación de Hibernate (Nhibernate)? ¿Cómo se usa unicode en HQL?

Varios sitios sugieren usar las consultas de Criterios. Debido a restricciones en el marco en el que estoy trabajando, esto no es posible.

¿Fue útil?

Solución

¿Has probado con parámetros:

IList<Person> people = session
    .CreateQuery("from Person p where p.Name like :name")
    .SetParameter("name", "%カタカ%")
    .List<Person>();

También tienen la ventaja de proteger su consulta contra la inyección de SQL.

Otros consejos

Encontré una solución que funciona. Dudo mucho que sea la mejor solución. Sin embargo, es la solución que voy a implementar hasta que pueda autorizar una reescritura de toda la sección de creación de consultas del software en el que estoy trabajando.

En la instancia:

SELECT P FROM SumTotal.TP.Models.Party.Person P join P.Demographics PD WHERE (PD.LastName LIKE '%カタカ%')

La cláusula where contiene este literal:

'%カタカ%'

Este literal se puede dividir en nchars que Hibernate (Nhibernate) pasará sin saberlo al SQL que genera. Extraño, pero funciona. Por lo tanto, la consulta anterior podría escribirse como:

SELECT P FROM SumTotal.TP.Models.Party.Person P join P.Demographics PD WHERE (PD.LastName LIKE '%' + nchar(0x30AB) + nchar(0x30BF) + nchar(0x30AB)+ '%')

Esta solución está lejos de ser óptima porque requeriría revisar cada carácter y determinar si era un carácter multibyte. Sin embargo, en el caso de que este código viva en su aplicación, se usa en un generador de consultas dinámico que procesa múltiples criterios diferentes bajo diferentes operaciones. En el ejemplo que doy, está buscando unicode en cualquier parte de la cadena. Es posible que esta función esté devolviendo la parte de la cláusula where para una columna que equivale a un valor numérico específico o podría estar buscando los caracteres iniciales de una cadena. El método que crea el operador utiliza un tipo de operador y el término para devolver una cadena. Podría reescribir eso, pero sería una gran tarea. La solución anterior me permitirá procesar una cadena pasada a este método. Ofrezco esta solución porque funciona, pero la respuesta de Darin es probablemente la mejor manera que pude encontrar.

Este problema surge porque NHibernate intenta acceder a la columna sin la longitud del tipo. Por lo tanto, en el HBM.xml es muy importante mencionar la longitud de las bases de datos heredadas; de lo contrario, fallará para las cosas relacionadas con UNIcode.

Gracias Thani

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