1

-- x86_64-pc-linux-gnu 上的 PostgreSQL 9.6.2,由 gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-17) 编译,64 位。

-- 从官方存储库安装。

-- postgresql.conf 没有任何变化。

-- CentOS 6.8 版。

-- 用户:postgres。

-- 使用 BigSQL 的 pgAdmin3 LTS。

-- 没有任何异常登录服务器。

我有很多疑问。

在这种情况下,我需要将字符变化数据类型(可能是表字段)与整数值进行比较。

--结果为真或假

select '10' = 10; 
select '10' = '10'; 
select '10'::character varying = '10'::character varying; 
select '10'::character varying = 'foo bar'; 
select '10'::character varying = 'foo bar'::character varying; 
select 'foo bar' = 'foo bar'; 
select '10'::character varying = '10';

--结果是“运算符不存在:字符变化 = 整数”

select '10'::character varying = 10; 

所以我创建了一个自定义运算符比较字符变化和整数

第 1 步:创建简单函数

CREATE OR REPLACE FUNCTION public.is_equal_char_int(character varying, integer) RETURNS boolean AS 
$BODY$ 
BEGIN 
    IF $1 = $2::character varying THEN
        RETURN TRUE;
    ELSE 
        RETURN FALSE; 
    END IF;
End;
$BODY$ 
LANGUAGE plpgsql VOLATILE COST 100;

第 2 步:创建新运算符

CREATE OPERATOR public.=( 
PROCEDURE = is_equal_char_int,
LEFTARG = character varying,
RIGHTARG = integer);

所以我解决了我的问题

select '10'::character varying = 10;

返回真值。

新问题是:当我将字符变化值与未知数据类型值进行比较时,postgresql使用我的自定义运算符

select '10'::character varying = 'foo bar';

结果是:

整数的无效输入语法:“foo bar”

select pg_typeof('foo bar');

返回未知的数据类型。

下一步我创建新的运算符来比较字符变化和未知数据类型。

步骤1:

CREATE OR REPLACE FUNCTION public.is_equal_char_unknown(character varying, unknown)
RETURNS boolean AS
$BODY$
BEGIN
IF $1 = $2::character varying THEN
    RETURN TRUE;
ELSE
    RETURN FALSE;
END IF;
End;
$BODY$
LANGUAGE plpgsql VOLATILE COST 100;

第2步:

CREATE OPERATOR public.=( 
PROCEDURE = is_equal_char_unknown,
LEFTARG = character varying,
RIGHTARG = unknown);

当我跑步时

select '10'::character varying = 'foo bar';

我给

错误:运算符不是唯一的:字符变化 = 未知。

所以我在一个洞里。

4

1 回答 1

2

要了解 PostgreSQL 中运算符的类型解析是如何完成的,请阅读文档中的运算符类型解析规则

在您的特殊情况下,步骤 3.a 之后仍保留以下运算符:

  • 您的自定义运算符 ( character varying = integer)。

  • character = charactercharacter varying(从到 的隐式转换character)。

  • name = namecharacter varying(从到 的隐式转换name)。

  • text = textcharacter varying(从到 的隐式转换text)。

然后规则 3.c 选择您的运算符,因为它是唯一具有精确类型匹配的运算符。如果没有您的运算符,步骤 3.d 会选择text = text,因为text它是字符串类别的唯一首选类型。

您目前正在做的是发现为什么某些运算符在 PostgreSQL 中定义,即为新类型组合定义新的比较运算符会导致歧义,从而导致错误,因为 PostgreSQL 无法决定使用哪个运算符。

问题的核心是 PostgreSQL重载运算符的能力,即有多个同名的运算符。然而,这是一个很好的功能,演员和操作员的系统已经过仔细平衡,以使体验尽可能好。该unknown类型也是该系统的一部分。

换句话说,PostgreSQL 试图猜测你的意思,但这并不总是可能的。如果你想比较一个(不是unknown)字符串和一个数字,你想要什么?应该将它们作为数字还是字符串进行比较?应该'010'一样10还是不一样?PostgreSQL 不知道你的意思并放弃了。

于 2017-05-14T04:24:35.603 回答