2

SQL では、次のような人物の名前を検索するクエリを作成できます。

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

このクエリは Unicode 文字で実行されます (Name 列とデータベースが Unicode サポートを処理するように設定されていると仮定します)。

Hibernate (NHibernate) によって実行される HQL に同様のクエリがあります。生成されたクエリは次のようになります。

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

残念ながら、HQL でリテラルの前に「N」を置くと、エラーが発生します。文字列内の Unicode 文字をエスケープしようとしましたが、まだ成功しません。

データベースは、Hibernate から Unicode 文字を受け入れて保存しています。オブジェクトに Unicode 文字列を正常に取り込み、Hibernate で保存し、データベースで検証することができました。カスタムクエリでユニコード文字列を使用できないのは少し奇妙に思えます (または、名前付きクエリも想定しています)。

これは Hibernate (Nhibernate) の既知の問題または制限ですか? HQLでユニコードをどのように使用しますか?

いくつかのサイトでは、Criteria クエリの使用を提案しています。私が取り組んでいるフレームワークの制約により、これは不可能です。

4

3 に答える 3

2

パラメータを試しましたか:

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

また、クエリを SQL インジェクションから保護するという利点もあります。

于 2009-01-15T17:34:39.457 に答える
2

うまくいく解決策を見つけました。私はそれが最善の解決策であることを非常に疑っています。ただし、これは、私が取り組んでいるソフトウェアのクエリ構築セクション全体の書き直しを承認できるまで、実装しようとしているソリューションです。

インスタンスでは:

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

where 句には、次のリテラルが含まれています。

'%カタカ%'

このリテラルは、Hibernate (Nhibernate) が無意識のうちにそれが生成する SQL に渡す nchar に分割できます。奇妙ですが、うまくいきます。したがって、前のクエリは次のように記述できます。

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

このソリューションは、各文字を調べてマルチバイト文字かどうかを判断する必要があるため、最適とは言えません。ただし、このコードがアプリ内に存在する場合、さまざまな操作で複数の異なる基準を処理する動的クエリ ジェネレーターで使用されます。私が与える例では、文字列内のどこでもユニコードを探しています。この関数は、特定の数値に等しい列の where 句の部分を返しているか、文字列の開始文字を探している可能性があります。演算子を作成するメソッドは、演算子の型と項を使用して文字列を返します。私はそれを書き直すことができましたが、それは大きな仕事になるでしょう。上記の修正により、このメソッドに渡された文字列を処理できるようになります。機能するため、このソリューションを提供しますが、ダーリン

于 2009-01-15T19:47:02.857 に答える
0

この問題は、NHibernate が型の長さを指定せずに列にアクセスしようとするために発生します。したがって、HBM.xml では、レガシー データベースの長さについて言及することが非常に重要です。そうしないと、UNIcode 関連のもので失敗します。

ありがとう、タニ

于 2011-04-07T09:54:42.357 に答える