当前位置:  开发笔记 > 前端 > 正文

用于返回给定表的动态列集的函数

如何解决《用于返回给定表的动态列集的函数》经验,为你挑选了1个好方法。

我有一个fields表来存储其他表的列信息:

CREATE TABLE public.fields (
   schema_name varchar(100), 
   table_name  varchar(100), 
   column_text varchar(100), 
   column_name varchar(100), 
   column_type varchar(100) default 'varchar(100)', 
   column_visible boolean
);

我想创建一个函数来获取特定表的数据.刚试过这样的事:

create or replace function public.get_table(schema_name text,
                                            table_name text,
                                            active boolean default true)
  returns setof record as $$

declare 
    entity_name text default schema_name || '.' || table_name;
    r record;
begin
    for r in EXECUTE 'select * from ' || entity_name loop
        return next r;
    end loop;
    return;
end
$$
language plpgsql;

使用此功能,我必须在调用它时指定列!

select * from public.get_table('public', 'users') as dept(id int, uname text);

我想根据表中的字段传递schema_nametable_name作为参数来起作用并得到记录列表.column_visiblepublic.fields



1> Erwin Brands..:

简单案例的解决方案

如下面引用的答案中所述,您可以使用已注册(行)类型,从而隐式声明多态函数的返回类型:

CREATE OR REPLACE FUNCTION public.get_table(_tbl_type anyelement)
  RETURNS SETOF anyelement AS
$func$
BEGIN
   RETURN QUERY EXECUTE format('TABLE %s', pg_typeof(_tbl_type));
END
$func$ LANGUAGE plpgsql;

呼叫:

SELECT * FROM public.get_table(NULL::public.users);  -- note the syntax!

返回完整的表(包含所有用户列).

等待!怎么样?

本相关答案的详细说明,"各种完整的表类型"一章 :

重构PL/pgSQL函数以返回各种SELECT查询的输出

TABLE foo只是简称SELECT * FROM foo:

SELECT*FROM有快捷方式吗?

完全动态返回类型的2个步骤

但是,您尝试做的事情在单个 SQL命令中是完全不可能的.

我想根据表中的字段 传递schema_nametable_name作为参数来起作用并得到记录列表.column_visiblepublic.fields

没有直接的方法可以从函数或任何 SQL命令返回任意选择的列(在调用时未知的返回类型).SQL要求在调用时知道结果列的数量,名称和类型.更多在相关答案的第2章:

如何在生成的表定义未知的情况下生成一个透视的CROSS JOIN?

有各种解决方法.你可以在标准文档类型(包的结果json,jsonb,hstore,xml).

或者您使用一个函数调用生成查询并使用下一个执行结果:

CREATE OR REPLACE FUNCTION public.generate_get_table(_schema_name text, _table_name text)
  RETURNS text AS
$func$
   SELECT format('SELECT %s FROM %I.%I'
               , string_agg(quote_ident(column_name), ', ')
               , schema_name
               , table_name)
   FROM   fields
   WHERE  column_visible
   AND    schema_name = _schema_name 
   AND    table_name  = _table_name
   GROUP  BY schema_name, table_name
   ORDER  BY schema_name, table_name;
$func$  LANGUAGE sql;

呼叫:

SELECT public.generate_get_table('public', 'users');

这会创建一个表单查询:

SELECT usr_id, usr FROM public.users;

在第2步执行它.
(您可能希望添加列号和顺序列.)
确保防范SQL注入:

在触发器函数中使用动态表名INSERT

在plpgsql函数中将表和列名定义为参数?

旁白

varchar(100) 对标识符没有多大意义,标准Postgres中限制为63个字符:

标签中的最大字符数(表名,列等)

如果您了解对象标识符类型的regclass工作方式,则可以使用单列替换模式和表名称regclass.

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有