You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中fn_login返回多行时变量声明及权限校验的fn_search实现

PostgreSQL函数开发疑问解答

示例表结构与数据

CREATE TABLE employee
(
    joining_date date,
    employee_type character varying,
    name character varying 
);
insert into employee VALUES
    (NULL,'as','hjasghg'),
    ('2022-08-12', 'Rs', 'sa'),
    (NULL,'as1','hjasghg1'),
    ('2024-09-12', 'Rs1', 'sa1'),
    (NULL,'as2','hjasghg2'),
    ('2023-12-12', 'Rs2', 'sa2'),
    (NULL,'asktyuk12','hjasg21');

疑问解答

1. listname应声明为text还是record?

既不能用text也不适合用单个record变量。因为fn_login(loginid)返回的是多行多列的结果(姓名+joining_date):

  • text只能存储单个文本值,完全无法承载多行多列的数据集;
  • 单个record变量只能存储一行数据,没法容纳多行结果。

正确的做法是将listname声明为集合类型,有两种常用方式:

  • 方式一:先自定义复合类型,再声明变量为该类型的集合
-- 创建自定义类型
CREATE TYPE employee_access AS (name text, joining_date date);
-- 在函数中声明变量
listname SETOF employee_access;
  • 方式二:直接用TABLE语法声明变量结构
listname TABLE(name text, joining_date date);

2. 如何利用该变量过滤出当前登录ID可访问的记录?

因为listname是多行权限数据集,你可以通过关联查询或者IN子查询的方式,在employee表中筛选出匹配权限的记录,以下是两种实现示例:

方式一:JOIN关联过滤

将employee表与fn_login(loginid)的结果关联,只保留匹配姓名的记录:

SELECT e.employee_type, e.name
FROM employee e
JOIN fn_login(loginid) l ON e.name = l.name;

方式二:IN子查询过滤

如果仅通过姓名过滤,直接用子查询提取fn_login返回的姓名列表:

SELECT e.employee_type, e.name
FROM employee e
WHERE e.name IN (SELECT name FROM fn_login(loginid));

如果需要结合joining_date做更复杂的权限校验(比如限定日期范围),可以调整关联条件或子查询的过滤逻辑。


内容的提问来源于stack exchange,提问作者codeanonym

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 00:47:21