在数据迁移时,出现错误:运算符不存在:布尔 = 整数提示:没有运算符与给定的名称和参数类型匹配
Posted
技术标签:
【中文标题】在数据迁移时,出现错误:运算符不存在:布尔 = 整数提示:没有运算符与给定的名称和参数类型匹配【英文标题】:On Data migration, getting error: operator does not exist: boolean = integer Hint: No operator matches the given name and argument types 【发布时间】:2021-05-11 03:09:34 【问题描述】:将数据库 mysql v5 迁移到 postgres v12 后,Java Spring 应用程序显示以下错误: 错误:运算符不存在:布尔 = 整数 提示:没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换。
【问题讨论】:
【参考方案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;
这可能工作量太大了。您最好在 Java 中将 int
转换为 String
,然后以这种方式进行比较;
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 代码以比较真/假关键字而不是整数:
-- do this
SELECT * FROM table WHERE bool_col = <true/false>;
-- instead of this
SELECT * FROM table WHERE bool_col = <val>;
【讨论】:
【参考方案2】:布尔类型检查因数据库而异(即从 mysql 到 postgres)。考虑下面我所经历的例子。 基础实体类 BaseEnity 有一个 active 布尔类型的列,Order 实体类扩展了该类。要选择所有活动订单,mysql 查询是:
select * from Order where active = 1
但是当将数据库迁移到 postgres 时它不起作用。在 postgres 中,它显示错误 operator does not exist: boolean = integer。正如 postgres 所期望的那样:
select * from Order where active = true
由于 postgres 需要布尔值 true/false,但在 SQL 查询中,该值被设置为整数类型 1,我们遇到了提示错误。
【讨论】:
【参考方案3】:这个怎么样?
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 的相对新手,我不建议您在数据库中创建大量随机隐式转换,但我认为这是可能的,这很有趣。随时警告危险。
附:我正在考虑是否更好的语义是 0=false,非零=true。取决于您的用例。
【讨论】:
以上是关于在数据迁移时,出现错误:运算符不存在:布尔 = 整数提示:没有运算符与给定的名称和参数类型匹配的主要内容,如果未能解决你的问题,请参考以下文章