使用JPA的WHERE中不允许使用PostgreSQL集返回函数

问题描述

我有一个看起来像这样的sql函数

CREATE OR  replace FUNCTION search(IN word character varying) 
returns setof certificates AS $$SELECT c 
FROM   certificates c 
WHERE  Upper(description) LIKE Upper('%\'||word||'%') 
OR Upper(NAME) LIKE Upper('%\' 
              ||word 
              ||'%') $$ language sql;

我正在尝试使用JPA来调用它,例如:

SELECT c FROM Certificates c WHERE c in (function('search',:findPhrase ))

我得到set-returning functions are not allowed in WHERE 但是,如果我将sql函数的返回类型更改为仅证书而不是setof证书,它将起作用。但它只找到1条记录。 我正在尝试不同的方法包括将结果强制转换为数组并使用id而不是整个对象。没有什么真正的帮助。 所以问题是:如何使我的代码按需工作?

我简化了我的实际案例,只显示有问题的部分。整个sql看起来更像:

SELECT c FROM Certificates 
JOIN c.tags t WHERE t.name IN :names "
"GROUP BY (c.id) "
"HAVING COUNT(c.id) >= :size
  AND c IN (function('search',:findPhrase )) 

最后,我将TypedQuery切换为NativeQuery并使用了这段代码

AND c in(select search(:findPhrase))

所以整个sql现在看起来像

SELECT * FROM certificates c JOIN certificate_tags ct ON c.id = ct.certificate_id JOIN tags t ON t.id = ct.tag_id WHERE t.name IN (?) GROUP BY (c.id,ct.id,t.id) HAVING COUNT(c.id) >= ? AND c in(select search(?))

解决方法

您需要select函数返回的集合。我想你只是想要:

select * from function('search',:findPhrase) c

Postgres甚至允许:

select function('search',:findPhrase) c