Domanda

In SQL è possibile scrivere una query che cerca il nome di una persona come questa:

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

Questa query verrebbe eseguita con caratteri unicode (supponendo che la colonna Nome e il database fossero configurati per gestire il supporto unicode).

Ho una query simile in HQL eseguita da Hibernate (NHibernate). La query generata è simile a:

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

Sfortunatamente, mettere una 'N' davanti al valore letterale nell'HQL provoca un errore. Ho provato a sfuggire ai caratteri unicode nella stringa e ancora non ci sono riuscito.

Il database sta accettando e salvando caratteri unicode da Hibernate. Sono stato in grado di popolare correttamente un oggetto con una stringa unicode, salvarlo con Hibernate e verificarlo nel database. Mi sembra un po 'strano che non riesca a usare stringhe unicode nelle query personalizzate (o presumo anche query con nome).

È un problema noto o una limitazione di Hibernate (Nhibernate)? Come si usa unicode in HQL?

Diversi siti suggeriscono di utilizzare le query dei criteri. A causa di vincoli nel framework in cui sto lavorando, questo non è possibile.

È stato utile?

Soluzione

Hai provato con i parametri:

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

Hanno anche il vantaggio di proteggere la tua query dall'iniezione SQL.

Altri suggerimenti

Ho trovato una soluzione che funziona. Dubito fortemente che sia la soluzione migliore. È comunque la soluzione che implementerò fino a quando non potrò autorizzare una riscrittura dell'intera sezione di creazione di query del software su cui sto lavorando.

Nell'istanza:

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

La clausola where contiene questo valore letterale:

'%カタカ%'

Questo letterale può essere suddiviso in nchars che Hibernate (Nhibernate) passerà inconsapevolmente all'SQL che genera. Strano, ma funziona. Pertanto la query precedente potrebbe essere scritta come:

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

Questa soluzione è tutt'altro che ottimale perché richiederebbe di esaminare ogni personaggio e determinare se fosse un personaggio multibyte. Tuttavia, nel caso in cui questo codice risieda nella sua app, viene utilizzato in un generatore di query dinamico che elabora più criteri diversi in operazioni diverse. Nell'esempio che dò sta cercando Unicode in qualsiasi punto della stringa. È possibile che questa funzione stia restituendo la porzione della clausola where per una colonna uguale a un valore numerico specifico oppure potrebbe cercare i caratteri iniziali di una stringa. Il metodo che crea l'operatore utilizza un tipo di operatore e il termine per restituire una stringa. Potrei riscriverlo, ma sarebbe un grosso compito. La correzione precedente mi permetterà di elaborare una stringa passata in questo metodo. Offro questa soluzione perché funziona, ma la risposta di darin è probabilmente il modo migliore che ho trovato.

Questo problema sorge perché NHibernate tenta di accedere alla colonna senza la lunghezza del tipo. Quindi in HBM.xml è molto importante menzionare la lunghezza per i database Legacy, altrimenti fallirà per cose relative a UNIcode.

Grazie, Thani

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top