#sql #grails #hql
#sql #grails #hql
Вопрос:
Я пытаюсь понять, как заставить этот фрагмент кода работать:
def searchString = unchecked.join(",");
searchString = searchString.replace(""", "'")
println("searchString: " searchString);
def matches=Employee.executeQuery("select e.id from Employee as e INNER JOIN Education as ed ON e.id = ed.employee_id INNER JOIN education_type AS et ON et.id = ed.type_id WHERE et.name in (" searchString ")");
Это строка запроса, переданная в ExecuteQuery
select e.id from Employee as e INNER JOIN Education as ed ON e.id = ed.employee_id INNER JOIN education_type AS et ON et.id = ed.type_id WHERE et.name in ('AA','BS')
который я могу запустить на SQL Server, и он возвращает правильные результаты, однако мой код grails жалуется:
Stacktrace follows:
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ON near line 1, column 59 [select e.id from Employee as e INNER JOIN Education as ed ON e.id = ed.employee_id INNER JOIN education_type AS et ON et.id = ed.type_id WHERE et.name in ('AA','BS')]
Итак, что я делаю не так? Это неправильный объект домена, выполняющий запрос?
Ответ №1:
Подумайте о том, чтобы сделать это так:
def employee = Employee.withCriteria {
education {
educationType {
in("name", ["AA", "BS"])
}
}
}
Ответ №2:
HQL немного / достаточно отличается от стандартного SQL. Предполагая, что Hibernate знает о взаимосвязи между этими объектами, вы можете упростить свой запрос до
List<String> typeNames = unchecked.collect { it.replace(""", "") }
String query = """FROM Employee e
WHERE e.education.educationType.name IN (:typeNames)"""
List<Employee> = Employee.executeQuery(query, [typeNames: typeNames])
Очень важно использовать либо именованные параметры, либо позиционные параметры в вашем запросе, чтобы предотвратить внедрение sql. Кроме того, если вам действительно нужен просто список идентификаторов сотрудников, а не экземпляров, вы можете поместить SELECT e.id
туда обратно. Также нет причин включать кавычки, поскольку, когда параметры привязаны, они будут использовать правильные кавычки для базы данных, с которой вы работаете, учитывая, что приведенный выше фрагмент кода также удаляет кавычки, но вы можете передумать, даже разрешив их включить в первую очередь.
Комментарии:
1. это дает мне неожиданный токен для: в запросе. Я не думал, что вы могли бы использовать список в типе параметра, отправляемого в запрос HQL
2. Извините, попробуйте заключить в круглые скобки именованный параметр, например
(:typeNames)
3. Спасибо. Я тоже понял это после некоторого поиска в Google. Я думаю, мне придется немного поработать с этим. У меня возникает проблема с тем, что educationType является коллекцией в разделе Education