#sql #postgresql #jpa #sql-function
#sql #postgresql #jpa #sql-функция
Вопрос:
У меня есть функция 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 на просто сертификаты вместо набора сертификатов, это сработает. Но он находит только 1 запись.
Я пробовал разные вещи, включая преобразование результата в массив и использование идентификаторов вместо целых объектов. На самом деле ничего не помогает.
Итак, вопрос в том, как заставить мой код работать по желанию?
Я упростил свой реальный случай, чтобы просто показать проблемную часть. Весь 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(?))
Ответ №1:
Вам нужно select
указать набор, который возвращает функция. Я думаю, вы просто хотите:
select * from function('search',:findPhrase) c
Postgres даже позволяет:
select function('search',:findPhrase) c
Комментарии:
1. Я попытался ВЫБРАТЬ c ИЗ Certificates JOIN c.теги t, ГДЕ t.name В : имена » «ГРУППИРУЮТСЯ ПО (c.id ) » «ИМЕЯ КОЛИЧЕСТВО (c.id ) >= :size И c В ( выберите функцию (‘search’,:findPhrase) ), Но теперь он говорит: Нет типа данных для узла
2. @DenisBahlei: похоже, это другая проблема. Пожалуйста, начните с выполнения этого запроса, как указано, и посмотрите, работает ли он.
3. Итак, я попытался запустить этот SELECT c ИЗ GiftCertificate c, ГДЕ c в (select function (‘search’,:findPhrase)), и у меня нет типа данных для узла: org.hibernate.hql.internal.ast.tree. MethodNode