Как создать функцию StartsWith для типа char (n) с конечным пробелом - PullRequest
0 голосов
/ 06 июля 2018

Мне нужно создать функцию setswith, которая возвращает true, если база данных char (n) столбец начинается с некоторых символов, которые Может содержать место в конце. Пробелы должны обрабатываться как другие символы.

База данных имеет два значения «А» и «АА». Я хочу, чтобы 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? Использование Postgres начиная с 9.1

Андрус.

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 голосов
/ 07 июля 2018

С 8.3. Типы символов :

Значения типа character физически дополняются пробелами до указанной ширины n и сохраняются и отображаются таким образом. Тем не менее, отступы рассматриваются как семантически незначимые. Конечные пробелы не учитываются при сравнении двух значений типа character, и они будут удалены при преобразовании значения character в один из других строковых типов. Обратите внимание, что конечные пробелы семантически значимы в значениях character varying и text, а также при использовании сопоставления с образцом, например, LIKE, регулярные выражения.

Обратите внимание, что аргументы вашей функции text. Когда вы передаете его, столбец test и литерал 'A ', test теряют завершающие пробелы при неявном приведении, тогда как литерал - нет. В вашей функции вы получите что-то вроде

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

что не соответствует действительности.

Вы можете перегрузить свою функцию и создать ее копию, где первым аргументом является char, или просто использовать регулярные выражения вместо определения собственной функции, например test ~ '^A ' или rtrim() пробелов из char и относиться к нему как к "безбрежному", как rtrim(test) LIKE 'A%' Я бы предпочел один из последних.

...