Postgresql函数用动态表名创建表?

Posted

技术标签:

【中文标题】Postgresql函数用动态表名创建表?【英文标题】:Postgresql function to create table with dynamic table name? 【发布时间】:2021-12-30 12:11:58 【问题描述】:

假设我有几个用户,每个用户都有自己的一组联系人。用户可以选择哪些第三方可以访问他们的联系人。

我可能会创建 1 个大型联系人表并有一个“所有者”列,以便我可以识别哪些联系人属于哪些用户。但是,我需要维护行级权限,以便我可以限制哪些第 3 方有权/无权访问特定的用户联系人。

相反,我认为(在这里我可能会弄错)为每个用户创建一个联系人表更有意义,例如:contact_e878df81_eba1_4a61_b592_30ac7100362a。然后我可以在单独的表中管理权限。

要创建这些“动态联系人表”,我有以下功能:

CREATE OR REPLACE FUNCTION create_contact_table(IN tbl_name text) RETURNS INT AS $$
DECLARE
    table_name text;
BEGIN
    table_name = tbl_name;
    create table IF NOT EXISTS table_name
    (
        id serial  not null
            constraint test_pkey
                primary key,
        firstname varchar not null,
        lastname varchar not null,
        age int not null,
        address varchar not null,
        email varchar not null,
        created timestamp default CURRENT_TIMESTAMP
    );
    alter table table_name
        owner to postgres;
    RETURN 1;
END ;

$$ LANGUAGE plpgsql;

当我执行函数时(create_contact_table(contact_e878df81_eba1_4a61_b592_30ac7100362a),创建了表,但是表的名字是table_name...

这是为什么呢?如何修复它以使表名正确?

【问题讨论】:

不,最好为所有所有者提供一张桌子。行级权限通常用于最多有几个用户的受控环境。但是...您似乎正在为许多同时用户设计一个应用程序。 你需要dynamic SQL 为每个用户都有一个联系人表更有意义” - 不,绝对不是。事实上,这是一个糟糕的主意。 @TheImpaler 你的意思是表级权限,对吧? "然后我可以在单独的表中管理权限" - 如果需要,您仍然可以在使用行级安全策略时这样做。 【参考方案1】:

您只能使用dynamic SQL 进行操作,例如:

CREATE OR REPLACE FUNCTION create_contact_table(tbl_name text)
 RETURNS boolean
 LANGUAGE plpgsql
AS $function$
declare
    v_sql text; 
    t1 text;
begin

    v_sql = '
    create table %I
    (
        id serial  not null
            constraint test_pkey
                primary key,
        firstname varchar not null,
        lastname varchar not null,
        age int not null,
        address varchar not null,
        email varchar not null,
        created timestamp default CURRENT_TIMESTAMP
    );
    ';
    
    raise notice 'SQL:: %', v_sql;

    EXECUTE format(v_sql, tbl_name);

    return true; 
          
END;
$function$
;

【讨论】:

以上是关于Postgresql函数用动态表名创建表?的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL - 作为表名的动态值[重复]

PostgreSQL COPY 命令中动态生成的表名

如何在 PostgreSQL 触发器函数中获取表名?

GreenPlum/PostgreSQL 创建函数返回数据集

PostgreSQL用啥命令查询所有表名

PostgreSQL 别名