2017-03-14 20 views
0

所以我有问题,我使用的PostgreSQL数据库有多个零售商作为一个模式。这些零售商在公共架构的表格中定义。所以我需要一个SQL脚本DAT可以先检索通过他们的public.tenants表和循环所有这些零售商选择与.programs表零售商的模式:SQL查询循环多个动态模式en梳理结果在工会

SELECT * FROM a.programs; 
SELECT * FROM b.programs; 

我已经尝试了一些变化,但无法找到一个方法来找出这一个。

SQL脚本我曾尝试:

DO 
$do$ 
DECLARE 
    tables CURSOR FOR 
     SELECT tenantid 
     FROM public.tenants; 
BEGIN 
FOR scheme_name IN tables LOOP 
    EXECUTE format('SELECT * FROM %s.%s',scheme_name, 'programs'); 
END LOOP; 
END 
$do$; 

这给了以下的输出:

ERROR: syntax error at or near ")" 
LINE 1: SELECT * FROM (a).programs 
         ^
QUERY: SELECT * FROM (a).programs 
CONTEXT: PL/pgSQL function inline_code_block line 8 at EXECUTE 
********** Error ********** 

ERROR: syntax error at or near ")" 
SQL state: 42601 
Context: PL/pgSQL function inline_code_block line 8 at EXECUTE 

如何让EXECUTE不采取in()围绕动态架构的名字吗?或者这个应用程序根本不可能?

请帮我拿出这个:)

回答

1

您有多个错误。 即时错误是您引用记录从循环,而不是该记录的单个字段,并且括号是记录的默认字符串显示的一部分。

您还应该使用%I作为占位符,用于标识符以正确处理引用。

于是立即错误是把这个固定的:

DO 
$do$ 
DECLARE 
    tables CURSOR FOR 
     SELECT tenantid 
     FROM public.tenants; 
BEGIN 
FOR rec IN tables LOOP 
    EXECUTE format('SELECT * FROM %I.%I', rec.tenantid, 'programs'); 
END LOOP; 
END 
$do$; 

但这仍然行不通的,因为你不能这样的,从一个匿名PL/PGSQL块返回结果。你需要将它放入一个函数:

create or replace function all_programs() 
    returns setof a.programs -- or returns table (...) 
as 
$$ 
declare 
    tables CURSOR FOR 
     SELECT tenantid 
     FROM public.tenants; 
BEGIN 
    FOR rec IN tables LOOP 
    return query EXECUTE format('SELECT * FROM %I.%I', rec.tenantid, 'programs'); 
    END LOOP; 
END 

$$ 语言plgpgsql;

然后使用:

select * 
from all_programs(); 
+0

谢谢!我必须做一些事情才能工作,我也想要它,但现在可以继续:) –