postgres subselect使用字段值作为模式名称

时间:2014-10-28 06:25:49

标签: postgresql

有没有办法从架构中进行子选择,其中架构的名称取自主选择中某个字段的值?有点像这样:

create schema a;
create table a.foo(id int);
create schema b;
create table b.foo(id int);

create table public.schemalist (schemaname text);
insert into schemalist values ('a'),('b');

select 
schemaname,
(select count(*) from  schemaname.foo)
from public.schemalist;

但不知何故告诉Postgres在第二列中计算foo架构中的schemaname表...?

1 个答案:

答案 0 :(得分:0)

您正在尝试根据模型中存储的数据创建SQL语句。我相信实现这一目标的唯一方法是使用PL / pgSQL函数并在内部构建(和执行)动态语句。

但是,我会仔细检查设计。我以前曾经做过几次微笑的事情,但在每种情况下最好的解决办法就是摆脱这种功能。


编辑请注意,使用每个客户的架构设计并不是一个坏习惯,我自己提倡这种方法。我的观点是 - 不可能使用目录详细信息来指定在单个语句中查询哪些表。 SQL是声明性的,即DBMS将执行您在查询中明确提到的内容。

如何解决问题的几种方法:

  1. 为您创建专用架构作为服务注册器,并创建和维护一组视图,这些视图将跨越所有客户端的模式表。就像,如果你对检查订单感兴趣,那就去做吧:

    CREATE VIEW registrar.all_orders AS
    SELECT * FROM cust1.orders
    UNION ALL
    SELECT * FROM cust2.orders
    UNION ALL ...
    

    为每个感兴趣的表创建并维护一个专用视图。通过“维护”我的意思是 - 将新客户引入系统的过程也应该更新所有注册商的观点。

  2. 创建一个函数,在注册商的架构中再次动态生成您感兴趣的查询。这可能很棘手,因为你将无法创建这样一个通用的功能:

    • 您必须将其定义为RETURNS TABLE并明确定义列
    • 或者您可以将其定义为RETURNS SETOF record,但在这种情况下,您将被迫提供 调用函数时的列规范。
  3. 这两种方法都为您提供了引用数据库中单个对象的方法(使用已知标识符)并通过此抽象获取相关值列表。

    如果您拥有稳定数量的客户端(模式),我会选择#1;如果您经常添加和/或删除客户端,我会选择#2。