В SQL можно написать запрос, который ищет имя человека следующим образом:
SELECT * FROM Person P WHERE P.Name LIKE N'%ike%'
Этот запрос будет выполняться с символами Unicode (при условии, что столбец Name и база данных настроены для обработки поддержки Unicode).
У меня есть аналогичный запрос в HQL, который выполняется Hibernate (NHibernate). Сгенерированный запрос выглядит так:
SELECT P FROM SumTotal.TP.Models.Party.Person P join P.Demographics PD WHERE (PD.LastName LIKE '%カタカ%' )
К сожалению, размещение буквы «N» перед литералом в HQL приводит к ошибке. Я попытался избежать символов Юникода в строке, но все равно безуспешно.
База данных принимает и сохраняет символы Юникода из Hibernate. Мне удалось успешно заполнить объект строкой Unicode, сохранить его с помощью Hibernate и проверить его в базе данных. Мне показалось бы немного странным, что я не могу использовать строки Unicode в пользовательских запросах (или я также предполагаю именованные запросы).
Это известная проблема или ограничение Hibernate (Nhibernate)? Как использовать юникод в HQL?
Некоторые сайты предлагают использовать запросы критериев. Из-за ограничений в структуре, в которой я работаю, это невозможно.





Вы пробовали с параметрами:
IList<Person> people = session
.CreateQuery("from Person p where p.Name like :name")
.SetParameter("name", "%カタカ%")
.List<Person>();
Они также имеют то преимущество, что защищают ваш запрос от SQL-инъекции.
К сожалению, существует ограничение на количество параметров, используемых в запросе, так что это не окончательное решение.
Я нашел решение, которое работает. Я очень сомневаюсь, что это лучшее решение. Однако это решение, которое я собираюсь реализовать, пока я не разрешу перезапись всего раздела построения запросов программного обеспечения, над которым я работаю.
В случае:
SELECT P FROM SumTotal.TP.Models.Party.Person P join P.Demographics PD WHERE (PD.LastName LIKE '%カタカ%')
Предложение where содержит этот литерал:
'%カタカ%'
Этот литерал можно разбить на nchars, которые Hibernate (Nhibernate) неосознанно передает в генерируемый им SQL. Странно, но это работает. Таким образом, предыдущий запрос можно было бы записать как:
SELECT P FROM SumTotal.TP.Models.Party.Person P join P.Demographics PD WHERE (PD.LastName LIKE '%' + nchar(0x30AB) + nchar(0x30BF) + nchar(0x30AB)+ '%')
Это решение далеко не оптимальное, поскольку потребовало бы перебора каждого символа и определения того, является ли он многобайтовым символом. Однако в случае, если этот код находится в своем приложении, он используется в генераторе динамических запросов, который обрабатывает несколько различных критериев при разных операциях. В приведенном мной примере он ищет юникод в любом месте строки. Возможно, эта функция может возвращать часть предложения where для столбца, равного определенному числовому значению, или может искать начальные символы строки. Метод, создающий оператор, использует тип оператора и термин для возврата строки. Я мог бы это переписать, но это была бы большая задача. Вышеупомянутое исправление позволит мне обработать строку, переданную в этот метод. Я предлагаю это решение, потому что оно действительно работает, но ответ Дарина, вероятно, лучший способ, который я мог найти.
Это работает, это отличная идея, лучше, чем использование параметров, потому что у вас нет никаких ограничений.
Эта проблема возникает из-за того, что NHibernate пытается получить доступ к столбцу без указания длины типа. Следовательно, в HBM.xml очень важно указать длину для устаревших баз данных, иначе это не удастся для вещей, связанных с UNIcode.
Спасибо, Затем я
Я рекурсивно создаю сложную строку запроса с разными критериями и операциями. У меня есть провайдер, которому я передаю операцию и срок, чтобы вернуть часть «Нравится». Это сработало бы, если бы я этого не делал! Я надеялся, что это какой-то волшебный побег.