web-dev-qa-db-ja.com

postgresqlのコマンドをコピーしてデータを追加する

関数からcopyコマンドを実行しています

execute 'copy (select * from tableName) to ''/tmp/result.txt'''

正常に動作します。しかし、tableNameは動的であり、より多くのテーブルを持っています(ループで繰り返す)。 result.txtは最後の反復(テーブル)データのみを持っています。

必要に応じて、コマンドラインから\oまたは>>ファイルに追加する。しかし、私は関数を使用する必要があります。

私は http://shuber.io/reading-from-the-filesystem-with-postgres/ を読みます。一時テーブルを使用するソリューションを提案します。一時テーブルなしで同様のことを行うことはできますか? (アーカイブログは避けなければなりません)。一時テーブルを作成するとアーカイブログが作成されますか?

関数でcopyコマンドを使用して追加する方法はありますか?

4
Spike

Unixシステムを想定

postgreQSL 9.3以降

プログラムとしてcatを指定したPROGRAM句を使用します。

execute 'copy (select * from tableName) to PROGRAM ''cat >>/tmp/result.txt'''

これにより、ファイルを上書きする代わりに、/tmp/result.txtの末尾に結果が追加されます。

古いバージョンのPostgreSQL

名前付きパイプは、別のプロセスで結果を連結するために使用できます。例:

$ mkfifo /tmp/pgfifo
$ while true; do cat /tmp/pgfifo >>/tmp/result.txt; done

この最後のコマンドはブロックします。すべての結果が蓄積されるまで実行し、^ Cまたはkillで終了できます。

SQLでは、fifoに以下を供給する必要があります。

execute 'copy (select * from tableName) to ''/tmp/pgfifo'''
5
Daniel Vérité

私はあなたが(簡単に)それを行うことはできないと思います(少なくともあなたのPostgreSQLバージョンでは、ダニエルの answer を見てください)。ただし、確実にできることはアプローチを変更することであり、COPYのクエリ部分にあるすべてのテーブルからUNION ALLを実行します。つまり、ループは発生しませんが、収集したテーブル名からクエリを作成する必要があります。

結果は次のようになります

COPY (SELECT * FROM table1
      UNION ALL
      SELECT * FROM table2
      ...) 
    TO tmp/result.txt;

注:

  • psql関数などはありません。 psqlはPostgreSQLのクライアントです。ただし、組み込みコマンド(基本的には\で始まるすべてのもの)があります。
  • 「アーカイブログ」が何を意味するかはそれほど明確ではありません。それが先読みログ(WAL)である場合、上記のアプローチを使用すれば、心配する必要はありません。それ以外の場合は、 ログなしのテーブル を使用できます。
  • テーブルが大きい場合、システムが(大量の)一時ファイルを書き込む可能性があります。これにより、実行速度が遅くなる場合があります。
2
dezso