我正在试图弄清楚如何使这段代码工作:
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')]
那么我做错了什么?它是执行查询的错误域对象吗?
答案 0 :(得分:2)
考虑这样做:
def employee = Employee.withCriteria {
education {
educationType {
in("name", ["AA", "BS"])
}
}
}
答案 1 :(得分:0)
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注入非常重要。此外,如果您真的只想要一个员工ID列表而不是实例,您可以将SELECT e.id
放回去。也没有理由包含引号,因为当params绑定时,它们将使用您正在使用的数据库的正确引号,因为上面的代码片段也会删除引号,但您可能会重新考虑甚至让它们包含在第一名。