在 plpgsql 中包含 IF..ELSE 条件并生成动态查询
Include IF.. ELSE condition in plpgsql and generating dynamic query
大家好,我有 2 个 tables dcrhd(保存当前数据)和 dcrhd_arc(保存历史数据)和
我创建了一个函数来从论文中获取一些数据 tables.But 这个函数只满足了我一半的要求(它只检查来自 dcrhd table 的数据)我将在这里分享我的函数..
CREATE OR REPLACE FUNCTION dcr_report( --fin_year_flag,
finid integer, prdid integer, comp_cd CHARACTER varying, divid integer, fsid integer) RETURNS refcursor LANGUAGE 'plpgsql' AS $BODY$
DECLARE
ref refcursor;
BEGIN
open ref for SELECT hd.report_no,
hd.dcr_date,
coalesce(pr2.para_descr,' ') work_type,
coalesce(pr1.para_descr,' ') hq_type,
coalesce(rm.route_name,' ') route_name,
coalesce(hd.doctor_visits,0) doctor_visits,
coalesce(hd.stockist_visits,0) stockist_visits,
coalesce(hd.retailer_visits,0) retailer_visits,
hd.dcr_id,
fm.fs_name,
hd.fstaff_id,
CASE hd.status
WHEN 'A' THEN 'APPROVED'
WHEN 'D' THEN 'DISCARDED'
WHEN 'F' THEN 'FORWARDED'
WHEN 'E' THEN 'DRAFT'
END
status,
zsm.fs_name report1,
rsm.fs_name report2,
fm.geog_lvl1_hq,
fm.level_code,
coalesce(pm.para_descr,'SELF') joint_work,
fm.fs_code,
fm.emp_code,
coalesce(hd.doc_other,0) doc_other
FROM dcrhd hd
LEFT OUTER JOIN parameters pm ON hd.jfw = pm.para_code AND pm.para_type = 'JFW'
LEFT OUTER JOIN route_master rm ON rm.fstaff_id = hd.fstaff_id AND rm.route_id = hd.route_id AND rm.company_cd
= comp_cd
LEFT OUTER JOIN parameters pr1 ON pr1.para_code = hd.hq_exhq AND pr1.para_type = 'HQ_',
parameters pr2,
field_master fm,
field_master zsm,
field_master rsm
WHERE hd.period_id = prdid AND hd.fin_year_id = finid AND hd.fstaff_id = fm.fs_id AND fm.mgr_level4 =
zsm.fs_id AND fm.mgr_level3 = rsm.fs_id AND fm.fs_id =
CASE
WHEN fsid = 0 THEN fm.fs_id
ELSE fsid
END
AND fm.div_id =
CASE
WHEN divid = 0 THEN fm.div_id
ELSE divid
END
AND fm.fs_id = hd.fstaff_id AND fm.level_code = '005' AND pr2.para_code = hd.work_type AND pr2.
para_type = 'WTP' AND hd.company = comp_cd AND fm.company_cd = comp_cd
ORDER BY fm.fs_name,
dcr_date;
RETURN REF;
END;
$BODY$;
我的要求是我只想添加一个名为 'fin_year_flag'
的新参数
和 select 主人 table 相应地(例如,if fin_year_flag='current'
然后转到 dcrhd
否则转到 dcrhd_arc
我可以实现这个吗???
你们能分享一下您对此的想法吗???还有其他方法可以完全满足我的要求吗?我是 PostgreSQL 的新手,在互联网上用谷歌搜索了很多次,但找不到任何有用的东西。
您发布的代码很大,所以让我向您演示如何动态使用 table 名称,并通过简化它来 return 一个 CURSOR
。
我用示例行创建了两个 table。
create table dcrhd as select 'CURRENT' ::TEXT as col;
create table dcrhd_arc as select 'ARCHIVED'::TEXT as col;
这是一个对动态生成的查询使用 OPEN <refcursor> FOR EXECUTE
的函数。您需要使用另一个引号或使用 dollar quoting.
转义主 SQL 中的单引号
table 名称是使用 CASE
表达式中的 fin_year_flag
设置的。
CREATE OR REPLACE FUNCTION dcr_report( fin_year_flag TEXT)
RETURNS refcursor LANGUAGE plpgsql
AS $BODY$
DECLARE
ref refcursor;
v_table_name TEXT := CASE fin_year_flag
WHEN 'current' THEN 'dcrhd'
ELSE 'dcrhd_arc' END;
v_sql text := format('select col from %s',v_table_name );
BEGIN
open ref for EXECUTE v_sql ;
RETURN REF;
END;
$BODY$;
大家好,我有 2 个 tables dcrhd(保存当前数据)和 dcrhd_arc(保存历史数据)和 我创建了一个函数来从论文中获取一些数据 tables.But 这个函数只满足了我一半的要求(它只检查来自 dcrhd table 的数据)我将在这里分享我的函数..
CREATE OR REPLACE FUNCTION dcr_report( --fin_year_flag,
finid integer, prdid integer, comp_cd CHARACTER varying, divid integer, fsid integer) RETURNS refcursor LANGUAGE 'plpgsql' AS $BODY$
DECLARE
ref refcursor;
BEGIN
open ref for SELECT hd.report_no,
hd.dcr_date,
coalesce(pr2.para_descr,' ') work_type,
coalesce(pr1.para_descr,' ') hq_type,
coalesce(rm.route_name,' ') route_name,
coalesce(hd.doctor_visits,0) doctor_visits,
coalesce(hd.stockist_visits,0) stockist_visits,
coalesce(hd.retailer_visits,0) retailer_visits,
hd.dcr_id,
fm.fs_name,
hd.fstaff_id,
CASE hd.status
WHEN 'A' THEN 'APPROVED'
WHEN 'D' THEN 'DISCARDED'
WHEN 'F' THEN 'FORWARDED'
WHEN 'E' THEN 'DRAFT'
END
status,
zsm.fs_name report1,
rsm.fs_name report2,
fm.geog_lvl1_hq,
fm.level_code,
coalesce(pm.para_descr,'SELF') joint_work,
fm.fs_code,
fm.emp_code,
coalesce(hd.doc_other,0) doc_other
FROM dcrhd hd
LEFT OUTER JOIN parameters pm ON hd.jfw = pm.para_code AND pm.para_type = 'JFW'
LEFT OUTER JOIN route_master rm ON rm.fstaff_id = hd.fstaff_id AND rm.route_id = hd.route_id AND rm.company_cd
= comp_cd
LEFT OUTER JOIN parameters pr1 ON pr1.para_code = hd.hq_exhq AND pr1.para_type = 'HQ_',
parameters pr2,
field_master fm,
field_master zsm,
field_master rsm
WHERE hd.period_id = prdid AND hd.fin_year_id = finid AND hd.fstaff_id = fm.fs_id AND fm.mgr_level4 =
zsm.fs_id AND fm.mgr_level3 = rsm.fs_id AND fm.fs_id =
CASE
WHEN fsid = 0 THEN fm.fs_id
ELSE fsid
END
AND fm.div_id =
CASE
WHEN divid = 0 THEN fm.div_id
ELSE divid
END
AND fm.fs_id = hd.fstaff_id AND fm.level_code = '005' AND pr2.para_code = hd.work_type AND pr2.
para_type = 'WTP' AND hd.company = comp_cd AND fm.company_cd = comp_cd
ORDER BY fm.fs_name,
dcr_date;
RETURN REF;
END;
$BODY$;
我的要求是我只想添加一个名为 'fin_year_flag'
的新参数
和 select 主人 table 相应地(例如,if fin_year_flag='current'
然后转到 dcrhd
否则转到 dcrhd_arc
我可以实现这个吗???
你们能分享一下您对此的想法吗???还有其他方法可以完全满足我的要求吗?我是 PostgreSQL 的新手,在互联网上用谷歌搜索了很多次,但找不到任何有用的东西。
您发布的代码很大,所以让我向您演示如何动态使用 table 名称,并通过简化它来 return 一个 CURSOR
。
我用示例行创建了两个 table。
create table dcrhd as select 'CURRENT' ::TEXT as col;
create table dcrhd_arc as select 'ARCHIVED'::TEXT as col;
这是一个对动态生成的查询使用 OPEN <refcursor> FOR EXECUTE
的函数。您需要使用另一个引号或使用 dollar quoting.
table 名称是使用 CASE
表达式中的 fin_year_flag
设置的。
CREATE OR REPLACE FUNCTION dcr_report( fin_year_flag TEXT)
RETURNS refcursor LANGUAGE plpgsql
AS $BODY$
DECLARE
ref refcursor;
v_table_name TEXT := CASE fin_year_flag
WHEN 'current' THEN 'dcrhd'
ELSE 'dcrhd_arc' END;
v_sql text := format('select col from %s',v_table_name );
BEGIN
open ref for EXECUTE v_sql ;
RETURN REF;
END;
$BODY$;