web-dev-qa-db-ja.com

複数のスキーマにわたるクエリ、実行時まで不明

クエリを実行する必要がある複数のスキーマがあります。たとえば、スキーマは事前にわかっていません。

  • U111
  • U222
  • U333

これらの各スキーマの特定のテーブルからこれら3つのスキーマ全体を選択する必要があります。このクエリをこれら3つのスキーマ全体に配置できますか?もしそうなら、どうすればそれらをクエリできますか?スキーマ名は事前にわからないので、動的に構築する必要があります。

6
larkmullins

複数のスキーマからの結果だけが必要な場合は、同じクエリ文字列を再利用してsearch_pathの間:

SET search_path = u111, public;
SELECT * FROM foo;
SET search_path = u222, public;
SELECT * FROM foo;
...

スキーマ検索パス search_path Postgresでは、ファイルシステムの検索パスと同じように機能します。関連:

複数のスキーマからの結果(おそらくユースケース)を組み合わせる必要がある場合は、クライアントでステートメントを作成するか、 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;

次の形式のクエリを動的に作成して実行します。

SELECT bar, baz FROM u111.foo
UNION ALL
SELECT bar, baz FROM u222.foo
UNION ALL
SELECT bar, baz FROM u333.foo;

SQLインジェクションを防ぐために、スキーマ名は識別子として適切にエスケープされます。

db <> fiddle here(クエリ文字列を実行する代わりにエラーメッセージとして返す)
古い sqlfiddle

8

テーブル構造が同じ場合は、テーブル継承を使用してから、すべてのテーブル構造を使用してマスタースキーマを作成し、他のテーブル構造からテーブルを継承させることができます。この手法について説明した記事は次のとおりです。

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

1
LR1234567