1. 程式人生 > >Oracle函式wm_concat移植到PostgreSQL注意事項

Oracle函式wm_concat移植到PostgreSQL注意事項

Oracle的包(package)中的程式碼片段如下:

 ---處理選單
         tempsql := 'insert into T_CALMENUFILTERCONFIG(ACCTSYSTYPE,NOTSHOWSUBMENU,ISSUE,USERID,HSAGENCY) ';
         tempsql :=tempsql||' select g.acctsystype,'''',1,t.userid,g.hsagency from t_cadataright t,t_acalmenurole g where t.roleid = g.roleid';
         tempsql :=tempsql||' and t.roleid = '||proleid||' and g.acctsystype='||pacctsystype||' and exists (select 1 from t_causer us where us.type < 1 and t.userid = us.userid) ';
         if pproxy = 1 then  -- 代理
            tempsql :=tempsql||' and g.hsagency='||phsagency||' and g.proxy=1';
           
            execute immediate tempsql;
            -- 處理隱藏選單
            tempsql :='update T_CALMENUFILTERCONFIG c set c.notshowsubmenu = (';
            tempsql := tempsql||' select to_char(wm_concat(g.menuid)) from t_acalmenurole g where g.acctsystype ='||pacctsystype||' and g.hsagency='||phsagency||' and g.proxy=1 and g.roleid='||proleid||')';
            tempsql := tempsql||' where c.acctsystype='||pacctsystype||' and c.hsagency='||phsagency||' and c.userid in (';
            tempsql := tempsql||' select d.userid from t_cadataright d where d.roleid = '||proleid||')';
            
            execute immediate tempsql;
         else
            tempsql :=tempsql||' and nvl(g.hsagency,0)=0 and nvl(g.proxy,0)=0';
           
            execute immediate tempsql;
            -- 處理隱藏選單行轉列到使用者
            tempsql :='update T_CALMENUFILTERCONFIG c set c.notshowsubmenu = (';
            tempsql := tempsql||' select to_char(wm_concat(g.menuid)) from t_acalmenurole g where g.acctsystype ='||pacctsystype||' and nvl(g.hsagency,0)=0 and nvl(g.proxy,0)=0 and g.roleid='||proleid||')';
            tempsql := tempsql||' where c.acctsystype='||pacctsystype||' and nvl(c.hsagency,0)=0  and c.userid in (';
            tempsql := tempsql||' select d.userid from t_cadataright d where d.roleid = '||proleid||')';
            
            execute immediate tempsql;

移植到PostgreSQL上的程式碼如下:

tempsql := 'insert into T_CALMENUFILTERCONFIG(ACCTSYSTYPE,NOTSHOWSUBMENU,ISSUE,USERID,HSAGENCY) ';
			tempsql := tempsql || ' select g.acctsystype,'''',1,t.userid,g.hsagency from t_cadataright t,t_acalmenurole g where t.roleid = g.roleid';
			tempsql := tempsql || ' and t.roleid = ' || proleid || ' and g.acctsystype=' || pacctsystype || ' and exists (select 1 from t_causer us where us.type < 1 and t.userid = us.userid) ';
			if pproxy = 1 then
				tempsql := tempsql || ' and g.hsagency=' || phsagency || ' and g.proxy=1';
				execute immediate tempsql;
				tempsql := 'update T_CALMENUFILTERCONFIG c set c.notshowsubmenu = (';
				tempsql := tempsql || ' select to_char(string_agg(menuid,'','')) from t_acalmenurole g where g.acctsystype =' || pacctsystype || ' and g.hsagency=' || phsagency || ' and g.proxy=1 and g.roleid=' || proleid || ')';
				tempsql := tempsql || ' where c.acctsystype=' || pacctsystype || ' and c.hsagency=' || phsagency || ' and c.userid in (';
				tempsql := tempsql || ' select d.userid from t_cadataright d where d.roleid = ' || proleid || ')';
				--raise notice 'tempsql is: %',tempsql; 
				execute immediate tempsql;
			else
				tempsql := tempsql || ' and nvl(g.hsagency,0)=0 and nvl(g.proxy,0)=0';
				execute immediate tempsql;
				tempsql := 'update T_CALMENUFILTERCONFIG c set c.notshowsubmenu = (';
				tempsql := tempsql || ' select to_char(string_agg(g.menuid,'','')) from t_acalmenurole g where g.acctsystype =' || pacctsystype || ' and nvl(g.hsagency,0)=0 and nvl(g.proxy,0)=0 and g.roleid=' || proleid || ')';
				tempsql := tempsql || ' where c.acctsystype=' || pacctsystype || ' and nvl(c.hsagency,0)=0  and c.userid in (';
				tempsql := tempsql || ' select d.userid from t_cadataright d where d.roleid = ' || proleid || ')';
				execute immediate tempsql;

注意:如果

string_agg(g.menuid,',')

裡面的逗號使用單引號雖然編譯能通過,可是在呼叫儲存過程時報如下

錯誤:

ERROR:  query "SELECT tempsql || ' select to_char(string_agg(menuid,',')) from t_acalmenurole g where g.acctsystype =' || pacctsystype || ' and g.hsagency=' || phsagency || ' and g.proxy=1 and g.roleid=' || proleid || ')'" returned 2 columns
CONTEXT:  edb-spl function pkg_afsp_roletouser.handelrole(integer,integer,integer,integer) line 32 at assignment
line 34 of package body
SQL state: 42601

後來改為2個單引號即可(原因是這裡的單引號需要轉義,sql中的單引號'即為轉義,相當於java中的反斜槓\),如上圖所示。