Имейте в виду, что null = null
, true = null
и false = null
все вычисляют как null
, что рассматривается как false
в предложении where
. Если вам нужно что-то еще, перефразируйте свой вопрос. Давайте посмотрим на таблицу истинности для (:status is null and status in (true,false)) or status = :status
.
|-------------|-------------|-------------|
| :status | status | result |
|-------------|-------------|-------------|
| null | null | false |
| null | true | true |
| null | false | true |
| true | null | false |
| true | true | true |
| true | false | false |
| false | null | false |
| false | true | false |
| false | false | true |
|-------------|-------------|-------------|
Другими словами, вам нужно предложение, которое всегда возвращает false
, когда status
равно null
. Это оставляет true
, если :status
равно null
, или истину, если :status
и status
имеют одинаковое значение.
status is not null and (:status is null or status = :status)
в качестве альтернативы
status is not null and coalesce(:status, status) = status
Обратите внимание, что это все еще не работает для описанной вами ошибки, потому что :status
привязан как BYTEA
Hibernate, когда вы передаете null
в Java. Вы можете обойти это, выполнив двойное приведение.
CAST(CAST(:status AS CHARACTER VARYING) AS BOOLEAN)
Если это именно то, что вы намеревались, результат будет:
SELECT *
FROM products
WHERE status IS NOT NULL
AND anotherStatus IS NOT NULL
AND COALESCE(CAST(CAST(:status AS CHARACTER VARYING) AS BOOLEAN), status) = status
AND COALESCE(CAST(CAST(:anotherStatus AS CHARACTER VARYING) AS BOOLEAN), anotherStatus) = anotherStatus