在数据迁移时,出现错误:运算符不存在:布尔 = 整数提示:没有运算符与给定的名称和参数类型匹配

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。取决于您的用例。

【讨论】:

以上是关于在数据迁移时,出现错误:运算符不存在:布尔 = 整数提示:没有运算符与给定的名称和参数类型匹配的主要内容,如果未能解决你的问题,请参考以下文章

带有 Sqlite 错误的 Laravel 迁移:typeSet 不存在

Python中的布尔值列表到整数

python数据类型强制转换和运算符

P4 开发实践 — 编程基础 — 数据类型

布尔逻辑运算符

SSH整合时,一直不成功,出现如下错误,错误太多了,不知道怎么改.