我在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 **********
问题是什么?我是以正确的方式连接的吗?
答案 0 :(得分:0)
如果我正确解析您的查询,那么这部分看起来是错误的:
where 'metadata @> ''{"Year":"2011"}'' and metadata @> ''{"Country":"US"}'' and ' versionflag=true
在where
和versionflag=true
之间,您有一个字符串文字(单引号字符串)。所以对于postgresql来说,它基本上看起来像你写的where 'string' versionflag=true
没有任何意义。看起来像是比较而缺少逻辑运算符。
答案 1 :(得分:0)
我解决了这个问题。 '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$;