如何实现包含字符串的运算符,如果左侧字符串包含在右侧字符串中,则返回true。
运营商名称可以是任意名称。我试过@@和代码,但是
select 'A' @@ 'SAS'
返回false。
如何解决?
CREATE OR REPLACE FUNCTION public.contains(searchFor text, searchIn text)
RETURNS bool
AS $BODY$ BEGIN
RETURN position( searchFor in searchIn)<>0;
END; $BODY$ language plpgsql immutable RETURNS NULL ON NULL INPUT;
CREATE OPERATOR public.@@ (
leftarg = text,
rightarg = text,
procedure = public.contains
);
在Windows和Linux中使用Postgres 9.1及以上版本。
select contains('A' , 'SAS' )
按预期返回true。
更新
我在回答中尝试了9.1代码:
CREATE OR REPLACE FUNCTION public.contains(searchFor text, searchIn text)
RETURNS bool
LANGUAGE sql IMMUTABLE
AS $BODY$
SELECT position( searchFor in searchIn )<>0;
$BODY$;
CREATE OPERATOR public.<@ (
leftarg = text,
rightarg = text,
procedure = public.contains
);
但收到错误
ERROR: column "searchin" does not exist
LINE 5: SELECT position( searchFor in searchIn )<>0;
如何让它在9.1中运行?在9.3中它起作用。
使用
“x86_64-unknown-linux-gnu上的PostgreSQL 9.1.2,由gcc-4.4 .real编译(Debian 4.4.5-8)4.4.5,64位”
答案 0 :(得分:2)
PostgreSQL已经在@@
架构的(text,text)
上定义了pg_catalog
运算符,其定义为:
regress=> \do @@
List of operators
Schema | Name | Left arg type | Right arg type | Result type | Description
------------+------+---------------+----------------+-------------+-------------------
pg_catalog | @@ | text | text | boolean | text search match
这优先于您在@@
架构中定义的public
。
我建议<@
使用contains
运算符,因为that's consistent with the array contains and contained-by operators。 pg_catalog
text
中没有对pg_catalog
使用它...但不保证在将来的版本或扩展中不会添加。
如果您希望保证您的运算符优先于pg_catalog
中的运算符,则需要将它们放在不同的模式中,并在CREATE SCHEMA my_operators;
CREATE OR REPLACE FUNCTION my_operators.contains(searchFor text, searchIn text)
RETURNS bool
LANGUAGE sql IMMUTABLE
AS $BODY$
SELECT position( searchFor in searchIn)<>0;
$BODY$;
CREATE OPERATOR my_operators.<@ (
leftarg = text,
rightarg = text,
procedure = public.contains
);
之前明确地将其放在搜索路径上。如下所示:
SET search_path = 'my_operators, pg_catalog, public';
然后
ALTER USER
您可以使用ALTER DATABASE
和/或{{1}}将其设为默认值。