【发布时间】:2016-05-19 10:28:12
【问题描述】:
我经常需要提交几乎相同的查询,但参数不同(单个参数,但在SELECT … 子句中多次(不是WHERE(!)))。
为了说明,它在duc.opt_level >= 5 /*v_min_level*/ 出现在下面的每个地方:
SELECT duc.id_du, duc.du_type_cd, duc.du_name, duc.du_addr, duc.id_du_def, duc.def_repeat_flg, defc.allows_txt_flg
,r.lvl + CASE duc.du_type_cd WHEN 'e' THEN CASE WHEN duc.opt_level >= 5 /*v_min_level*/ AND duc.max_occurs=1 THEN 0 ELSE 1 END ELSE 0 END lvl
,CASE duc.du_type_cd WHEN 'e' THEN CASE WHEN duc.opt_level >= 5 /*v_min_level*/ AND duc.max_occurs=1 THEN r.id_du ELSE duc.id_du END ELSE r.id_du END entid
,CASE duc.du_type_cd WHEN 'e' THEN CASE WHEN duc.opt_level >= 5 /*v_min_level*/ AND duc.max_occurs=1 THEN r.entraw ELSE duc.du_addr END ELSE r.entraw END entraw
,CASE duc.du_type_cd WHEN 'e' THEN CASE WHEN duc.opt_level >= 5 /*v_min_level*/ AND duc.max_occurs=1 THEN r.entnm ELSE duc.du_name END ELSE r.entnm END entnm
,CASE duc.du_type_cd WHEN 'e' THEN CASE WHEN duc.opt_level >= 5 /*v_min_level*/ AND duc.max_occurs=1 THEN r.pentid ELSE r.entid END ELSE r.pentid END pentid
,CASE duc.du_type_cd WHEN 'e' THEN CASE WHEN duc.opt_level >= 5 /*v_min_level*/ AND duc.max_occurs=1 THEN r.pentraw ELSE r.entraw END ELSE r.pentraw END pentraw
,CASE duc.du_type_cd WHEN 'e' THEN CASE WHEN duc.opt_level >= 5 /*v_min_level*/ AND duc.max_occurs=1 THEN r.pentnm ELSE r.entnm END ELSE r.pentnm END pentnm
,defc.def_type, defc.val_type
,defc.is_nillable
,defc.optional
FROM r
JOIN data_unit duc
ON duc.id_parent_du = r.id_du
JOIN du_def defc
ON defc.id_du_def = duc.id_du_def
…
Postgres 版本。 9.5.1
有什么优雅的方法可以参数化这个查询,这样我就可以只通过重新定义这个参数来调用它?
我想到了类似于 匿名 PL/pgSQL 块的东西,但我不知道具体是怎么回事
【问题讨论】:
-
似乎可以避免嵌套 CASE。
-
例如存储函数或PREPARE/EXECUTE statements。
-
@joop 怎么样?你的意思是把
CASE … WHEN改写成CASE WHEN …? -
@Abelisto with PREPARE/EXECUTE 恐怕它需要我放很多
?然后用多个但相同的参数调用:execute pblock(5,5,5,5,5,5,…) -
不,只是在查询中多次使用
$1,fe:select $1, $1 || $1 ...
标签: sql postgresql parameters plpgsql reusability