Postgresql

從表中複製了多少行

  • January 12, 2018

我想編寫一個腳本來使用COPY.

psql "connection parameters" -c "COPY (SELECT * FROM tbl WHERE insertion_date > 'date') TO STDOUT WITH CSV HEADER;" | bzip2 -c > backup.csv.bz2

現在我想記錄有多少行被複製到 zip 文件中?我想在複製時計算它,而不是用另一個命令。

**更新:**由於 Postgres 9.3 plpgsql 可以COPY直接訪問處理的行數:


我最近遇到了同樣的問題。我嘗試使用 plpgsql 函式,但在 Postgres 9.2 或更早版本中ROW_COUNT沒有設置- 。COPY

可以只執行兩個查詢。首先count(),然後COPY。通過簡單的查詢,這可能是要走的路。但是對於巨大/複雜的查詢,這是一種痛苦,並且可以使執行時間加倍。

我想出了一個使用臨時表並在執行之前計算行數的解決方案COPY

我為您調整了我擁有的內容,以便您可以通過COPY TO STDOUT管道傳輸到bzip2,這在 plpgsql 函式中是不可能的:

1. 創建一個函式,該函式接受一個 SQL 字元串並用它創建一個臨時表:

CREATE OR REPLACE FUNCTION f_copy_prep(_query text)
 RETURNS void AS
$func$
DECLARE
  ct integer;
BEGIN
  -- If you deal with huge results, set more RAM for temp tables locally:
  -- SET temp_buffers = 512MB';  -- example value

  EXECUTE 'CREATE TEMP TABLE cp_tmp ON COMMIT DROP AS (' || _query || ')';

  GET DIAGNOSTICS ct = ROW_COUNT;
  RAISE LOG 'My text here. rows: %', ct;

END
$func$  LANGUAGE plpgsql;
ALTER FUNCTION f_copy_prep(text) SET search_path=public,pg_temp;
REVOKE ALL ON FUNCTION f_copy_prep(text) FROM public;
GRANT EXECUTE ON FUNCTION f_copy_prep(text) TO ???;
  • 函式執行動態 SQL,因此您可以將其用於任何查詢。
  • 這本質上是不安全的,因此請以必要的最低權限執行它,撤銷公共的所有權利並EXECUTE專門授予受信任的使用者。請按照手冊中的說明進行操作
  • 使用 創建臨時表ON COMMIT DROP,以便在事務結束時自動刪除它。
  • GET DIAGNOSTICS使用-獲取行數ROW_COUNT由 中的SELECT語句設置EXECUTE。將其寫入日誌 - 您的要求。無需單獨的count(*).

2. 從 shell-script 呼叫通過 bzip2 管道輸出

psql "connection parameters" \
-c "SELECT f_copy_prep('SELECT * FROM tbl WHERE insertion_date > ''date'''); \
   COPY cp_tmp TO STDOUT WITH CSV HEADER;" \
| bzip2 -c > backup.csv.bz2
  • 將兩個 SQL 命令放入您的-c參數或將復雜查詢放入一個文件並使用該-f參數。全部在一個事務中執行。僅返回最後一個命令的輸出 - 符合我們的需要。小心語法 - 多層解釋(第一個 shell,然後是 Postgres)。
  • 第一個命令是以查詢字元串為參數的上述函式。第二個是COPY TO STDOUT

PostgreSQL 9.1在 Linux 上對此進行了測試,它對我有用:文件中的數據,日誌中帶有行數的消息。

引用自:https://dba.stackexchange.com/questions/14766