" " postgresql 函数处或附近的语法错误

Posted

技术标签:

【中文标题】" " postgresql 函数处或附近的语法错误【英文标题】:syntax error at or near " " postgresql function 【发布时间】:2018-03-10 07:42:07 【问题描述】:

我在 postgresql 中有一个函数。不知道是不是我弄的有点复杂。我有一个选择查询,我需要在其中添加更多表达式。我将这些表达式作为输入参数传递。

CREATE OR REPLACE FUNCTION get_alldocuments(currUser text,
queryExp text,
query0 text,
query1 text)
RETURNS TABLE(fileleafref text,contenttypename text,fsobjtype text,id integer,conttypeid integer,contenttypeid integer,docicon text,encodedabsurl text,refId integer,filesizedisplay integer,created date,
createdby text,version text) AS $$

BEGIN
RETURN QUERY EXECUTE 'select distinct c.fileleafref, ct.contenttypename,c.fsobjtype,c.id,c.conttypeid,d.contenttypeid,c.docicon,c.encodedabsurl,d.ref_id as RefId,c.filesizedisplay,d.created,
                        d.createdby,c.version from public.documents d inner join public.documentcontent c on d.id=c.documentid inner join conttype ct on ct.id = c.conttypeid
                        where '
                         || quote_literal(queryExp) 
                         || ' versionflag=true and c.permissiontype ="1" or  (c.permissiontype="3" and c.createdby =currUser)  order by d.created desc limit 300)
                        union
                        (select distinct c.fileleafref, ct.contenttypename,c.fsobjtype,c.id,c.conttypeid,d.contenttypeid,c.docicon,c.encodedabsurl,d.ref_id as RefId,c.filesizedisplay,d.created,
                        d.createdby,c.version from public.documents d inner join public.documentcontent c on d.id=c.documentid inner join conttype ct on ct.id = c.conttypeid '
                        || quote_ident(query0) || 
                        ' where' || quote_ident(queryExp) || 'versionflag=true '|| quote_ident(query1) ||
                        ' order by d.created desc limit 300)';
END
$$ LANGUAGE plpgsql;

在函数中,我试图在我的选择查询的不同位置附加不同的表达式。

输入变量是

currUser -  user1
queryExp  - metadata @> ''"Year":"2011"'' and metadata @> ''"Country":"US"'' and 

query0  - ,jsonb_array_elements(c.securitygppermission) as e(users) ,jsonb_array_elements_text(c.userspermission) as p(perm) 


 query1 - and (c.permissiontype='2' and e.users ->>'Deny'='false' and e.users ->>'Allow'='true' and e.users ->>'GroupName'='Manager'  and p.perm ='user1')

完整的选择查询示例是

select * from get_alldocuments('user1','metadata @> ''"Year":"2011"'' and metadata @> ''"Country":"US"'' and ',',jsonb_array_elements(c.securitygppermission) as e(users) ,jsonb_array_elements_text(c.userspermission) as p(perm)','and (c.permissiontype="2" and e.users ->>"Deny"="false" and e.users ->>"Allow"="true" and e.users ->>"GroupName"="Manager"  and p.perm ="user1")')

在执行函数时,它会显示类似的错误

ERROR:  syntax error at or near "versionflag"
LINE 3: ...11"'' and metadata @> ''"Country":"US"'' and ' versionfla...
                                                         ^
QUERY:  select distinct c.fileleafref, ct.contenttypename,c.fsobjtype,c.id,c.conttypeid,d.contenttypeid,c.docicon,c.encodedabsurl,d.ref_id as RefId,c.filesizedisplay,d.created,
                        d.createdby,c.version from public.documents d inner join public.documentcontent c on d.id=c.documentid inner join conttype ct on ct.id = c.conttypeid
                        where 'metadata @> ''"Year":"2011"'' and metadata @> ''"Country":"US"'' and ' versionflag=true and c.permissiontype ="1" or  (c.permissiontype="3" and c.createdby =currUser)  order by d.created desc limit 300)
                        union
                        (select distinct c.fileleafref, ct.contenttypename,c.fsobjtype,c.id,c.conttypeid,d.contenttypeid,c.docicon,c.encodedabsurl,d.ref_id as RefId,c.filesizedisplay,d.created,
                        d.createdby,c.version from public.documents d inner join public.documentcontent c on d.id=c.documentid inner join conttype ct on ct.id = c.conttypeid ",jsonb_array_elements(c.securitygppermission) as e(users) ,jsonb_array_elements_text(c.userspermission) as p(perm)" where"metadata @> '""Year"":""2011""' and metadata @> '""Country"":""US""' and "versionflag=true "and (c.permissiontype=2 and e.users ->>""Deny""=""false"" and e.users ->>""Allow""=""true"" and e.users ->>""GroupName""=""Manager""  and p.perm =""user1"")" order by d.created desc limit 300)
CONTEXT:  PL/pgSQL function get_alldocuments(text,text,text,text) line 4 at RETURN QUERY
********** Error **********

有什么问题?我的连接方式是否正确?

【问题讨论】:

FORMAT 总是优先于这种连接。无论如何,我认为如果您使用 queryExp - metadata @> '"Year":"2011"' and metadata @> '"Country":"US"' and 它可能会起作用 @VaoTsun 删除该单引号将不起作用,因为它用作转义字符。我的选择查询已在问题中更新。 【参考方案1】:

如果我正确解析了您的查询,那么这部分看起来是错误的:

where 'metadata @> ''"Year":"2011"'' and metadata @> ''"Country":"US"'' and ' versionflag=true

whereversionflag=true 之间有一个字符串文字(单引号字符串)。所以对于 postgresql 来说,它基本上看起来就像你写了 where 'string' versionflag=true 这没有任何意义。看起来缺少比较和逻辑运算符。

【讨论】:

【参考方案2】:

我解决了这个问题。 'quote_indent' 造成了这个问题。最终的功能是

CREATE OR REPLACE FUNCTION public.get_alldocuments(
curruser text,
queryexp text,
query0 text,
query1 text)
RETURNS TABLE(fileleafref character varying, contenttypename character varying, fsobjtype character varying, id integer, conttypeid integer, contenttypeid character varying, docicon character varying, encodedabsurl character varying, refid character varying, filesizedisplay integer, created date, createdby character varying, version character varying) 
LANGUAGE 'plpgsql'
COST 100
VOLATILE 
ROWS 1000
AS $BODY$

BEGIN
RETURN QUERY EXECUTE '(select distinct c.fileleafref, ct.contenttypename,c.fsobjtype,c.id,c.conttypeid,cast(d.contenttypeid as varchar) as contenttypeid,c.docicon,c.encodedabsurl,d.ref_id as RefId,c.filesizedisplay,cast(d.created as date) created,
                        d.createdby,c.version from public.documents d inner join public.documentcontent c on d.id=c.documentid inner join conttype ct on ct.id = c.conttypeid
                        where '
                         || queryExp
                         ||  ' versionflag=true and c.permissiontype=''1'' or  (c.permissiontype=''3'' and c.createdby =''||  curruser ||'')  order by created desc limit 300)
                        union
                        (select distinct c.fileleafref, ct.contenttypename,c.fsobjtype,c.id,c.conttypeid,cast(d.contenttypeid as varchar) as contenttypeid,c.docicon,c.encodedabsurl,d.ref_id as RefId,c.filesizedisplay,cast(d.created as date) created,
                        d.createdby,c.version from public.documents d inner join public.documentcontent c on d.id=c.documentid inner join conttype ct on ct.id = c.conttypeid '
                        || query0 || 
                         ' where ' || queryExp || ' versionflag=true ' || query1 ||
                         'order by created desc limit 300);';
END

$BODY$;

【讨论】:

以上是关于" " postgresql 函数处或附近的语法错误的主要内容,如果未能解决你的问题,请参考以下文章

" " postgresql 函数处或附近的语法错误

如何从PostgreSQL json中提取数组

如何从postgresql中的字符串中删除特殊字符

PostgreSQL:在 Rails 迁移中使用 add_column "after" 选项

PostgreSQL 中的 数据类型 使用问题

带有 dapper 和 postgresql 的“WHERE x IN y”子句抛出 42601:在 \"$1\" 处或附近出现语法错误