我有一个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_name
和table_name
作为参数来起作用并得到记录列表.column_visible
public.fields
如下面引用的答案中所述,您可以使用已注册(行)类型,从而隐式声明多态函数的返回类型:
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有快捷方式吗?
但是,您尝试做的事情在单个 SQL命令中是完全不可能的.
我想根据表中的字段 传递
schema_name
和table_name
作为参数来起作用并得到记录列表.column_visible
public.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
.