Вопрос

На SQL можно написать запрос, который ищет имя человека, например:

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

Этот запрос будет выполняться с символами Юникода (при условии, что столбец Имя и база данных настроены для поддержки Юникода).

У меня есть аналогичный запрос в HQL, который выполняется Hibernate (NHibernate).Сгенерированный запрос выглядит так:

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

К сожалению, размещение буквы «N» перед литералом в HQL приводит к ошибке.Я пытался экранировать символы Юникода в строке, но безуспешно.

База данных принимает и сохраняет символы Юникода из Hibernate.Мне удалось успешно заполнить объект строкой Юникода, сохранить его в Hibernate и проверить в базе данных.Мне показалось бы немного странным, что я не могу использовать строки Юникода в пользовательских запросах (или я также предполагаю именованные запросы).

Это известная проблема или ограничение 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.

Спасибо Тани

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top