Строка Юникода в запросах гибернации - PullRequest
2 голосов
/ 15 января 2009

В 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 и проверить его в базе данных. Мне показалось бы немного странным, что я не могу использовать строки Юникода в пользовательских запросах (или я также предполагаю именованные запросы).

Это известная проблема или ограничение Hibernate (Nhibernate)? Как вы используете юникод в HQL?

Несколько сайтов предлагают использовать критерии критериев. Из-за ограничений в структуре, в которой я работаю, это невозможно.

Ответы [ 3 ]

2 голосов
/ 15 января 2009

Я нашел решение, которое работает. Я очень сомневаюсь, что это лучшее решение. Однако это решение я буду реализовывать до тех пор, пока не смогу разрешить переписать весь раздел построения запросов программного обеспечения, над которым я работаю.

В случае:

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 для столбца, равного конкретному числовому значению, или она может искать начальные символы строки. Метод, который создает оператор, использует тип оператора и термин для возврата строки. Я мог бы переписать это, но это было бы большой задачей. Вышеуказанное исправление позволит мне обработать строку, переданную в этот метод. Я предлагаю это решение, потому что оно работает, но ответ Дарина, вероятно, - лучший способ, который я смог найти.

2 голосов
/ 15 января 2009

Вы пробовали с параметрами:

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

Они также имеют преимущество для защиты вашего запроса от внедрения SQL.

0 голосов
/ 07 апреля 2011

Эта проблема возникает из-за того, что NHibernate пытается получить доступ к столбцу без длины типа. Следовательно, в файле HBM.xml очень важно упомянуть длину для баз данных Legacy, в противном случае произойдет сбой для материалов, связанных с UNIcode.

Спасибо, Thani

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...