-- PostgreSQL 9.6.2 on x86_64-pc-linux-gnu,由 gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-17) 编译,64 位。
-- 从官方存储库安装。
-- postgresql.conf 中没有任何变化。
-- CentOS 6.8 版本。
-- 用户:邮政。
-- 由 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;
返回真值。
新的问题是: 当我将字符变化值与 unkown 数据类型值进行比较时,PostgreSQL使用我的自定义运算符。
select '10'::character varying = 'foo bar';
结果是 :
整数的输入语法无效:"Foo bar">
select pg_typeof('foo bar');
返回未命名的数据类型。
下一步,我创建新的运算符来比较字符变化和unkown数据类型。
第 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';
我给
错误:运算符不是唯一的:字符变化 = 未知。
所以我在一个洞里。
要了解如何在 PostgreSQL 中为运算符进行类型解析,请阅读文档中的运算符类型解析规则。
在特殊情况下,步骤 3.a 之后仍保留以下运算符:
-
您的自定义运算符 (
character varying = integer
)。 -
character = character
(从character varying
到character
的隐式转换)。 -
name = name
(从character varying
到name
的隐式转换)。 -
text = text
(从character varying
到text
的隐式转换)。
然后,规则 3.c 选择您的运算符,因为它是唯一具有完全类型匹配的运算符。如果没有运算符,步骤 3.d 会选择text = text
,因为text
是字符串类别中唯一首选的类型。
您现在正在做的是发现为什么PostgreSQL中没有定义某些运算符,即为新类型组合定义新的比较运算符会导致歧义,从而导致错误,因为PostgreSQL无法决定使用哪个运算符。
问题的核心是PostgreSQL重载运算符的能力,即拥有多个具有相同名称的运算符。然而,这是一个很好的功能,演员和操作员的系统已经经过精心平衡,以使体验尽可能好。unknown
类型也是该系统的一部分。
换句话说,PostgreSQL试图猜测你的意思,但这并不总是可能的。如果你想比较一个(不是unknown
)字符串和一个数字,你想要什么?它们应该作为数字还是字符串进行比较?'010'
应该和10
一样吗?PostgreSQL不知道你的意思,放弃了。
通过定义如何在 varchar 和数字之间进行转换,可以有另一种选择:
CREATE CAST (VARCHAR AS NUMERIC) WITH INOUT AS IMPLICIT;
这样就可以进行这样的比较:
SELECT '1'::character varying = 1::int;
> true
SELECT '01'::character varying = 1::int;
> true
SELECT '2'::character varying = 1::int;
> false
select '10'::character varying = 'foo bar';
> false
有关在 postgresql 中创建强制转换的更多信息,请单击此处: https://www.postgresql.org/docs/current/sql-createcast.html