如何为带有结尾空格的char(n)类型创建StartsWith函数

时间:2018-07-06 08:54:12

标签: postgresql plpgsql postgresql-9.1

我需要创建startswith函数,如果char(n)数据库返回true 列以一些字符开头 末尾可能包含空格。 空格应与其他字符一样对待。

数据库具有两个值“ A”和“ AA”。我希望startwith('A')(不带尾部空格)与AA和A都匹配,而startwith('A')(带尾部空格)仅与A匹配。

在下面使用示例数据

startswith( test, 'A')   -- works
startswith( test, 'A  ')  -- returns wrong result : false
StartsWith(test, rpad('A',20) )  -- returns wrong result : false

应返回true

但是

startswith( test, RPAD( 'A', 21))

应该返回false,因为检查字符串的末尾有多余的空格。

数据库包含具有char(20)类型列的测试列,而这不能 改变了。

我在下面尝试了代码,但返回false。

如何解决此问题,使其返回true? 从9.1开始使用Postgres

安德鲁斯。

CREATE or replace FUNCTION public.likeescape( str text )
--  
https://stackoverflow.com/questions/10153440/how-to-escape-string-while-matching-pattern-in-postgresql
RETURNS text AS $$
SELECT replace(replace(replace($1,'^','^^'),'%','^%'),'_','^_') ;
$$ LANGUAGE sql IMMUTABLE;

CREATE or replace FUNCTION public.StartWith( cstr text, algusosa text )
RETURNS bool AS $$
SELECT $2 is null or $1 like likeescape($2) ||'%' ESCAPE '^' ;
$$ LANGUAGE sql IMMUTABLE;

create temp table test ( test char(20) ) on commit drop;
insert into test values ('A' );
insert into test values ('AA' );

select StartWith(test, 'A ' ) from test

我还将此邮件发布到了pgsql-general邮件列表中。

1 个答案:

答案 0 :(得分:1)

来自8.3. Character Types

  

类型character的值在物理上填充了指定宽度 n 的空格,并以此方式存储和显示。但是,填充空间在语义上不重要。比较两个character类型的值时,尾部空格将被忽略,而将character值转换为其他字符串类型之一时,尾部空格将被删除。请注意,尾随空格在character varyingtext值中以及在使用模式匹配(例如, LIKE,正则表达式。

请注意,函数的两个参数均为text。当您将其传递给列test和文字'A '时,test在隐式强制转换时会丢失尾随空格,而文字则不会。在您的函数中,您最终会得到类似

的信息
'A' LIKE 'A %' ESCAPE '^'

那是不正确的。

您可以重载函数并创建其副本,其中第一个参数为char,或仅使用正则表达式而不是定义自己的函数,例如test ~ '^A 'rtrim()char隔开,并像rtrim(test) LIKE 'A%'一样将其视为“无空间”。我更喜欢后者。