Postgresql
從表中複製了多少行
我想編寫一個腳本來使用
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 上對此進行了測試,它對我有用:文件中的數據,日誌中帶有行數的消息。