Question

En SQL, on peut écrire une requête qui cherche le nom d’une personne comme ceci:

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

Cette requête serait exécutée avec des caractères Unicode (en supposant que la colonne Nom et la base de données aient été configurées pour gérer le support Unicode).

J'ai une requête similaire dans HQL qui est exécutée par Hibernate (NHibernate). La requête générée ressemble à:

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

Malheureusement, placer un 'N' devant le littéral dans la HQL entraîne une erreur. J'ai essayé d'échapper aux caractères unicode de la chaîne et toujours sans succès.

La base de données accepte et enregistre les caractères Unicode de Hibernate. J'ai réussi à renseigner un objet avec une chaîne unicode, à l'enregistrer avec Hibernate et à le vérifier dans la base de données. Il me semblerait un peu étrange que je ne puisse pas utiliser de chaînes unicode dans les requêtes personnalisées (ou que je suppose aussi des requêtes nommées).

S'agit-il d'un problème connu ou d'une limitation d'Hibernate (Nhibernate)? Comment utilisez-vous Unicode dans HQL?

Plusieurs sites suggèrent d'utiliser les requêtes Critères. En raison de contraintes dans le cadre dans lequel je travaille, cela n’est pas possible.

Était-ce utile?

La solution

Avez-vous essayé avec les paramètres:

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

Ils ont également l'avantage de protéger votre requête contre l'injection SQL.

Autres conseils

J'ai trouvé une solution qui fonctionne. Je doute fort que ce soit la meilleure solution. C’est toutefois la solution que je vais mettre en œuvre jusqu’à ce que je puisse autoriser une réécriture de la totalité de la section de création de requêtes du logiciel sur lequel je travaille.

Dans l'instance:

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

La clause where contient ce littéral:

'%カタカ%'

Ce littéral peut être divisé en nchars que Hibernate (Nhibernate) transmettra sans le savoir au SQL qu’il génère. Bizarre, mais ça marche. Ainsi, la requête précédente pourrait s’écrire:

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

Cette solution est loin d’être optimale car elle nécessiterait de passer en revue chaque caractère et de déterminer s’il s’agissait d’un caractère multi-octets. Toutefois, dans les cas où ce code réside dans son application, il est utilisé dans un générateur de requête dynamique qui traite plusieurs critères différents dans différentes opérations. Dans l'exemple que je donne, il recherche l'unicode n'importe où dans la chaîne. Il est possible que cette fonction retourne la partie de la clause where pour une colonne égale à une valeur numérique spécifique ou qu'elle recherche les caractères de départ d'une chaîne. La méthode qui construit l'opérateur utilise un type d'opérateur et le terme pour rendre une chaîne. Je pourrais réécrire cela, mais ce serait une grosse tâche. Le correctif ci-dessus me permettra de traiter une chaîne passée dans cette méthode. Je propose cette solution car elle fonctionne, mais la réponse de darin est probablement la meilleure solution que je puisse trouver.

Ce problème se pose car NHibernate essaie d’accéder à la colonne sans la longueur du type. C’est pourquoi il est très important de mentionner la longueur des bases de données Legacy dans le fichier HBM.xml, faute de quoi il échouera pour les éléments liés à UNIcode.

Merci, Thani

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top