PL/pgSQL函数中如何定义setof bigint变量接收union查询结果
正确实现方案
PL/pgSQL 不支持直接声明 setof 类型的变量,你可以用 bigint[] 数组类型存储合并后的ID集合,再通过数组操作符完成存在性判断,和你原有逻辑完全等价:
CREATE FUNCTION xyz (base_id bigint) returns int language plpgsql as $$ DECLARE -- 声明数组类型存储所有允许的base id allowed_base_ids bigint[]; BEGIN -- 将两个函数返回的结果合并去重后转为数组赋值 allowed_base_ids := array( select get_owned_base_ids() UNION select get_bases_editable() ); -- 用数组ALL操作符判断base_id是否不在允许列表中 IF base_id <> ALL(allowed_base_ids) THEN -- 你的原有业务逻辑 return 1; END IF; return 0; END; $$;
补充说明
- 这里
UNION会自动对两个函数返回的ID去重,和你最初的写法逻辑完全一致,如果不需要去重可以换成UNION ALL获得更好的性能。 - 如果你不习惯数组操作符,也可以替换为
NOT (base_id = ANY(allowed_base_ids)),和上面的判断逻辑完全等价。
如果你不想用数组变量,也可以用CTE直接在判断逻辑里完成集合查询,性能和数组方案基本一致:
CREATE FUNCTION xyz (base_id bigint) returns int language plpgsql as $$ BEGIN IF NOT EXISTS ( WITH allowed AS ( select get_owned_base_ids() as id UNION select get_bases_editable() as id ) SELECT 1 FROM allowed WHERE id = base_id ) THEN return 1; END IF; return 0; END; $$;
内容的提问来源于stack exchange,提问作者AJP
相关产品推荐
相关产品推荐

