Сравните дату, если не ноль - PullRequest
0 голосов
/ 13 января 2019

Мне нужно найти все записи с датой создания> X. X является sql.Timestamp и может иметь значение null, и в этом случае я хочу просто вернуть все записи. Поэтому я попытался: (созданный после метки времени)

SELECT *
FROM sample AS s
WHERE s.isActive
  AND (:createdAfter ISNULL OR s.insert_time > :createdAfter)

Но все, что я получаю, это

org.postgresql.util.PSQLException: ERROR: could not determine data type of parameter $1

Однако, если я сделаю тот же запрос, где я проверяю, чтобы произвольный int был нулевым:

SELECT * 
FROM trades 
WHERE (:sInt ISNULL OR trades.insert_time > :createdAfter ) 

Тогда это работает. В чем дело?

Ответы [ 2 ]

0 голосов
/ 13 января 2019

Вы можете попробовать использовать функцию pg_typeof, которая возвращает текстовую строку, и использовать оператор CASE для принудительного выполнения сравнения (в противном случае нет никаких гарантий, что postgres закоротит OR в правильном порядке). , Затем вы можете принудительно выполнить правильное преобразование, преобразовав его в текст, а затем обратно в метку времени, которая неэлегатна, но должна быть эффективной.

SELECT *
FROM sample AS s
WHERE s.isActive
  AND 
    CASE WHEN pg_typeof( :createdAfter ) = 'bytea' THEN TRUE
       WHEN s.insert_time > ( ( :createdAfter )::text)::timestamp THEN TRUE
       ELSE FALSE 
    END
0 голосов
/ 13 января 2019

Нет простого решения, если вы хотите придерживаться подобных запросов. Значение null преобразуется в значение bytea. Смотрите, например, это и это .

Это значение довольно трудно преобразовать или сравнить со значением timestamp.

Проблема не столько в первом сравнении, сколько в решении проблемы с использованием coalesce, например:

COALESCE(:createdAfter) ISNULL

потому что нет никакого сравнения между фактическими значениями и типом данных, не имеет значения. Но сравнение

sometimestamp::timestamp > null::bytea (приводит только к показу реальных типов, поэтому не работает)

потребовалось бы больше логики для обработки процедур и исключений или около того, не уверен.

Так что, если JPQL или CriteriaQueries невозможны, у вас есть только плохие варианты:

  • создать запрос, установив параметры путем конкатенации строк или около того (НЕ! И не уверен, что все работает)
  • использовать PreparedStatement запросов, больше кода и усилий
  • также, если вы используете Hibernate, используя API сеанса, как в этот ответ
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...