首页 > 解决方案 > 如何为带有结尾空格的 char(n) 类型创建 StartsWith 函数

问题描述

我需要创建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

应该返回真

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

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

数据库包含具有 char(20) 类型列的测试列,并且无法更改。

我尝试了下面的代码,但它返回错误。

如何解决此问题以使其返回 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 邮件列表。

标签: postgresqlplpgsqlpostgresql-9.1

解决方案


8.3 开始。字符类型

typecharacter的值在物理上用空格填充到指定的宽度n,并以这种方式存储和显示。但是,填充空间在语义上被视为无关紧要。比较两个类型的值时,尾随空格被忽略,并且在将值转换为其他字符串类型之一character时,它们将被删除。character请注意,尾随空格在character varyingtext值中以及在使用模式匹配时(例如LIKE,正则表达式)具有语义意义。

请注意,您的函数的两个参数都是text. 当您将 columntest和 literal传递给它时'A 'test会在隐式强制转换时丢失尾随空格,而文字不会。在您的功能中,您最终会得到类似的东西

'A' LIKE 'A %' ESCAPE '^'

这不是真的。

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


推荐阅读