提问人:Jan Přibyl 提问时间:2/8/2023 最后编辑:ZegarekJan Přibyl 更新时间:2/8/2023 访问量:228
错误:运算符不存在:在 PostgreSQL 中将列类型 int 更改为 varchar 时,varchar >= 整数
ERROR: operator does not exist: varchar >= integer when changing column type int to varchar in PostgreSQL
问:
我的任务是创建一个 Liquibase 迁移,以将表 trp_order_sold 中的值 affext(现在是 int8)更改为 varchar(或任何其他文本类型,如果可能的话)。
我制作的脚本如下:
ALTER TABLE public.trp_order_sold
ALTER COLUMN affext SET DATA TYPE VARCHAR
USING affext::varchar;
我预计该部分将用作转换器,但是无论有没有它,我都会收到此错误:USING affext::text;
ERROR: operator does not exist: varchar >= integer
Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
关于我做错了什么的任何提示?此外,我正在编写一个PostgreSQL脚本,但一个有效的XML等效物对我来说也很好。
答:
2赞
Zegarek
2/8/2023
#1
这些最典型的是使用或依赖于您的列:
在我的测试(在线演示)中,只有最后一个会导致您显示的错误:
create table test_table(col1 int);
--CREATE TABLE
alter table test_table add constraint test_constraint check (col1 >= 1);
--ALTER TABLE
alter table test_table alter column col1 type text using col1::text;
--ERROR: operator does not exist: text >= integer
--HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
您必须使用 命令 或通过查询系统表来检查表的约束:\d+
psql
SELECT con.*
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel
ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp
ON nsp.oid = connamespace
WHERE nsp.nspname = 'your_table_schema'
AND rel.relname = 'your_table_name';
然后,您需要删除导致问题的约束,并构建一个新约束以使用您的新数据类型。
由于整数 20 在整数 100 之前,但文本“20”在文本“100”之后,因此如果您打算保留旧的排序行为,则需要这种类型的强制转换:
case when affext<0 then '-' else '0' end||lpad(ltrim(affext::text,'-'),10,'0')
然后,确保在插入和更新触发器中相应地强制转换新的传入值。或者使用与此类似的数字
ICU 排序规则。affext
评论
0赞
Jan Přibyl
2/8/2023
谢谢,这奏效了。问题确实在于制约因素。
评论
ALTER TABLE public.trp_order_sold ALTER COLUMN affext TYPE VARCHAR;
ERROR: operator does not exist: varchar >= integer