最近与软件商适配的时候碰到一个应用错误:
错误,42883,"操作符不存在: character varying = bytea",,"没有匹配指定名称和参数类型的操作符. 您也许需要增加明确的类型转换."
一、原因分析
如果在应用里含有等值条件判断的SQL,“=”左边是字符串类型(character varying),右边的值是输入值。此时,该输入值如果是空值(NULL),jdbc进行转换时就会出现误判,误认为控制是bytea类型的。而数据库又没有对应左右值类型的的操作符或针对bytea的类型转换,从而导致上面的错误提示。
二、处理方式
推荐从应用层面对输入值是否是空值进行判断控制分别进行处理:
- 如果是非空继续等值判断;
- 如果是空值,则使用“is [not] null”进行判断。
若是要从数据库层面来处理,则可以从两个角度来处理:
- 类型转换角度:
-- 函数 bytea_to_text
create or replace function bytea_to_text( bytea )
returns text
as $$
select convert_from($1, 'UTF8');
$$ language sql strict;
-- 隐士转换
create cast ( bytea as text )
with function bytea_to_text( bytea )
as implicit;
- 操作符角度:
-- 自定义操作符调用的函数
CREATE or replace FUNCTION varchar_equal_bytea( varchar, bytea )
RETURNS boolean
AS $$
SELECT $1::text::bytea = $2::bytea
$$ LANGUAGE SQL;
-- 创建“=”操作符
CREATE OPERATOR =(
PROCEDURE = varchar_equal_bytea,
LEFTARG = varchar,
RIGHTARG = bytea);
-- 给操作符增加注释
COMMENT ON OPERATOR =( varchar, bytea) IS ' varchar equals bytea ';
注意:
使用新增操作符,有时候应用里还会继续出现该错误。推荐使用类型转换,但更推荐在应用代码层面来处理这个问题。