跨多个模式查询,直到执行时间未知

lar*_*ins 6 schema postgresql dynamic-sql plpgsql

我有多个需要查询的模式。模式是事先未知的,例如:

  • U111
  • U222
  • U333

我需要从这些模式中的每一个中的特定表中选择这三个模式。我可以将这个查询放在这三个模式中吗?如果是这样,我如何查询它们?请记住,我不会提前知道模式名称,因此需要动态构建它们。

Erw*_*ter 10

如果您只需要来自多个模式的结果,您可以重复使用相同的查询字符串并设置search_path介于两者之间:

SET search_path = u111, public;
SELECT * FROM foo;
SET search_path = u222, public;
SELECT * FROM foo;
...
Run Code Online (Sandbox Code Playgroud)

search_pathPostgres 中的模式搜索路径与文件系统的搜索路径非常相似。有关的:

如果您需要组合来自多个模式的结果(可能是您的用例),您可以在客户端中构建语句或使用plpgsql 函数与动态 SQL 和EXECUTE. 这就是我会做的。普通 SQL 不允许参数化标识符(模式、表、列等)。

CREATE OR REPLACE FUNCTION foo(_schemas text[])
  RETURNS TABLE (bar int, baz text) AS  -- matching return type
$func$
BEGIN
   RETURN QUERY EXECUTE (
   SELECT string_agg(format('SELECT bar, baz FROM %I.foo', sch)  -- your query here
                          , E'\nUNION ALL\n')
   FROM   unnest(_schemas) sch
   );
END
$func$  LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

动态构建并执行以下形式的查询:

SELECT bar, baz FROM u111.foo
UNION ALL
SELECT bar, baz FROM u222.foo
UNION ALL
SELECT bar, baz FROM u333.foo;
Run Code Online (Sandbox Code Playgroud)

模式名称作为标识符正确转义以防止 SQL 注入。

db<>fiddle here(将查询字符串作为错误消息返回而不是执行它)
旧的sqlfiddle


LR1*_*567 1

如果您的表结构相同,您可以使用表继承,然后创建一个包含所有表结构的主模式,并让其他模式从该主模式继承表:这是我们写的一篇描述该技术的文章:

http://www.postgresonline.com/journal/archives/59-How-to-Inherit,-Unherit-and-Merge-Inherit.html