【问题标题】:How to create StartsWith function for char(n) type with ending space如何为带有结尾空格的 char(n) 类型创建 StartsWith 函数
【发布时间】:2018-12-14 20:01:46
【问题描述】:

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

数据库有两个值 '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) 类型列的测试列,这不能 改变了。

我尝试了下面的代码,但它返回 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 邮件列表。

【问题讨论】:

  • 我看不出前 3 个示例有什么问题。给定test = 'A',test 以 'A' 开头,不以 'A' 开头,也不以 'A ...' 开头。为什么不正确?
  • char(20) 用尾随空格填充。所以A 必须匹配。数据库有两个值 'A' 和 'AA' 。我希望 startwith('A') 返回 AA 和 A 但 startwith('A ') 只返回 A。我更新了问题
  • 这是不正确的。 CREATE TEMP TABLE t (txt CHAR(20)); INSERT INTO t VALUES ('A'); SELECT '_' || txt || '_' FROM t; 返回 _A_SELECT LENGTH(txt) FROM t; 返回 1

标签: postgresql plpgsql postgresql-9.1


【解决方案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%' 一样“无空间”。我更喜欢后者。

【讨论】:

  • 是否可以创建StartsWith 函数,该函数在将 char(n) 作为第一个参数传递给它时不会删除空格。对于不同的查询,n 可能不同。我试过StartsWith ( cstr char(n), StartOfCstrMayContainSpacesAtEnd text ),但这在语法上不正确。
  • @Andrus:只需使用 char 而不使用 (n)
猜你喜欢
  • 2010-12-17
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
相关资源
最近更新 更多