Запрос ВНУТРЕННЕГО СОЕДИНЕНИЯ HQL из Grails

#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