При переносе данных возникает ошибка: оператор не существует: логическое = целое число Подсказка: ни один оператор не соответствует заданному имени и типам аргументов
После переноса базы данных mysql v5 на postgres v12 приложение Java Spring показывает ошибку ниже: ОШИБКА: оператор не существует: boolean = integer Подсказка: ни один оператор не соответствует заданному имени и типам аргументов. Возможно, вам потребуется добавить явное приведение типов.
3 ответа
Проверка логического типа зависит от базы данных (например, от mysql до postgres). Рассмотрим приведенный ниже пример того, что я испытал. Базовый класс сущности BaseEnity {} имеет столбец с активным логическим типом, а класс сущности Order {} расширяет этот класс. Чтобы выбрать все активные заказы, запрос mysql был:
select * from Order where active = 1
Но при переносе базы данных на postgres ничего не вышло. В postgres он показывает, что оператор ошибки не существует: boolean = integer . Как ожидает postgres, запрос:
select * from Order where active = true
Поскольку postgres ожидает логическое значение true / false, но в SQL-запросе значение было установлено на целочисленный тип 1, мы столкнулись с ошибкой с подсказкой.
Это происходит потому, что вы создали столбец в таблице PostgreSQL с
boolean
тип. В MySQL логические значения представлены как целые числа (часто
bit
, чтобы сэкономить место), а в PostgreSQL нет неявного преобразования:
psql (12.4)
Type "help" for help.
postgres=# select true = 1;
ERROR: operator does not exist: boolean = integer
LINE 1: select true = 1;
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
postgres=#
Вы можете написать функцию, которая немного преобразует в логическое значение (а также наоборот), а затем создать неявное приведение:
-- you'll need to write your own `bit_to_boolean()` function
CREATE CAST (BIT AS BOOLEAN)
WITH FUNCTION bit_to_boolean(BIT)
AS IMPLICIT;
Это может быть слишком много работы. Возможно, вам лучше преобразовать свой
int
к
String
в Java выполните сравнение таким же образом;
postgres=# select true = 1;
ERROR: operator does not exist: boolean = integer
LINE 1: select true = 1;
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
postgres=# select true = '1';
?column?
----------
t
(1 row)
postgres=# select true = 't';
?column?
----------
t
(1 row)
postgres=# select true = 'f';
?column?
----------
f
(1 row)
postgres=# select true = '0';
?column?
----------
f
(1 row)
Другой способ, возможно, обойти проблему, которую вы видите, - это отредактировать код Java для сравнения ключевых слов true / false вместо целого числа:
-- do this
SELECT * FROM table WHERE bool_col = <true/false>;
-- instead of this
SELECT * FROM table WHERE bool_col = <val>;
Как насчет этого?
CREATE OR REPLACE FUNCTION equal_int_bool(x int, y bool)
RETURNS BOOLEAN AS $$
begin
return x = y::int;
end;
$$ LANGUAGE PLPGSQL IMMUTABLE STRICT;
CREATE OPERATOR = (
leftarg = INTEGER,
rightarg = BOOLEAN,
procedure = equal_int_bool);
CREATE OR REPLACE FUNCTION equal_bool_int(x bool, y int)
RETURNS BOOLEAN AS $$
begin
return x::int = y;
end;
$$ LANGUAGE PLPGSQL IMMUTABLE STRICT;
CREATE OPERATOR = (
leftarg = BOOLEAN,
rightarg = INTEGER,
procedure = equal_bool_int);
Примеры истин:
> select 0=false a, false=0 b, 1=true c, true=1 d;
a | b | c | d
---+---+---+---
t | t | t | t
Ожидайте false для всех других сравнений:
> select 1=false a, 0=true b, 2=true c, -1=true d, true=-1 e;
a | b | c | d | e
---+---+---+---+---
f | f | f | f | f
Примечание. Я относительный новичок в Postgresql и не рекомендую создавать множество случайных неявных преобразований в своей базе данных, но мне показалось интересным, что это возможно. Не стесняйтесь предупреждать об опасностях.
PS Я размышляю, будет ли лучшая семантика 0 = ложь, ненулевое значение = истина. Зависит от вашего варианта использования.