Postgresql
在 postgresql 中執行系統命令
我的要求是在觸發器執行時執行系統命令,如 (ls) 或 C 程序。有沒有辦法創建一個觸發函式來解決這個問題。
您可以輕鬆地執行*@a_horse_with_no_name*在他的評論中建議的操作。但也有一種有趣的方法可以做到這一點,使用 PL/pgSQL 作為函式語言。
這使用了
COPY
PostgreSQL 9.3 中引入的命令功能。它現在可以將命令作為目標/源,這正是您在正常情況下使用文件名或 STDIN/STDOUT 的位置:COPY table_name [ ( column_name [, ...] ) ] FROM { 'filename' | PROGRAM 'command' | STDIN } [ [ WITH ] ( option [, ...] ) ]
顯然,您需要一個表格來放置輸出,但如果您願意,可以忽略它。
看一個小例子:
CREATE TABLE trigger_test ( tt_id serial PRIMARY KEY, command_output text ); CREATE OR REPLACE FUNCTION trigger_test_execute_command() RETURNS TRIGGER LANGUAGE plpgsql AS $BODY$ BEGIN COPY trigger_test (command_output) FROM PROGRAM 'echo 123'; RETURN NULL; END; $BODY$; CREATE TABLE trigger_test_source ( s_id integer PRIMARY KEY ); CREATE TRIGGER tr_trigger_test_execute_command AFTER INSERT ON trigger_test_source FOR EACH STATEMENT EXECUTE PROCEDURE trigger_test_execute_command(); INSERT INTO trigger_test_source VALUES (2); TABLE trigger_test; tt_id │ command_output ───────┼──────────────── 1 │ 123
**注意:**該函式需要以超級使用者權限執行——也就是說,要麼以
INSERT
超級使用者身份執行,要麼使用SECURITY DEFINER
. 在任何其他情況下,您都會收到錯誤消息:ERROR: must be superuser to COPY to or from an external program HINT: Anyone can COPY to stdout or from stdin. psql's \copy command also works for anyone.
如果您只需要查看與
$PGDATA
您相關的內容,可以使用pg_ls_dataSELECT pg_ls_dir('pg_xlog');
否則,像這樣的簡單函式:
CREATE OR REPLACE FUNCTION ls(location text) RETURNS text AS $BODY$ use warnings; use strict; my $location = $_[0]; my $output = `ls -l $location`; return($output); $BODY$ LANGUAGE plperlu;
會給你這樣的輸出:
user1@[local]:5432:user1:=# SELECT * FROM ls('/usr/local/pgsql/data'); ls ----------------------------------------------------------------------------------------- total 104 + -rw------- 1 pgsql pgsql 4 Jan 14 14:33 PG_VERSION + drwx------ 8 pgsql pgsql 8 Jan 15 12:27 base + drwx------ 2 pgsql pgsql 54 Feb 4 01:30 global + drwx------ 2 pgsql pgsql 4 Jan 15 12:57 pg_clog + drwx------ 2 pgsql pgsql 2 Jan 14 14:33 pg_commit_ts + drwx------ 2 pgsql pgsql 2 Jan 14 14:33 pg_dynshmem + -rw------- 1 pgsql pgsql 4458 Feb 4 01:29 pg_hba.conf + -rw------- 1 pgsql pgsql 1725 Jan 20 15:29 pg_ident.conf + drwx------ 4 pgsql pgsql 5 Feb 4 02:14 pg_logical + drwx------ 4 pgsql pgsql 4 Jan 14 14:33 pg_multixact + drwx------ 2 pgsql pgsql 3 Feb 4 01:29 pg_notify + drwx------ 2 pgsql pgsql 2 Jan 14 14:33 pg_replslot + drwx------ 2 pgsql pgsql 2 Jan 14 14:33 pg_serial + drwx------ 2 pgsql pgsql 2 Jan 14 14:33 pg_snapshots + drwx------ 2 pgsql pgsql 2 Feb 4 01:29 pg_stat + drwx------ 2 pgsql pgsql 8 Feb 4 02:17 pg_stat_tmp + drwx------ 2 pgsql pgsql 3 Jan 15 13:08 pg_subtrans + drwx------ 2 pgsql pgsql 2 Jan 14 14:33 pg_tblspc + drwx------ 2 pgsql pgsql 2 Jan 14 14:33 pg_twophase + lrwxr-xr-x 1 pgsql pgsql 29 Jan 14 14:34 pg_xlog -> /usr/local/pgsql/xlog/pg_xlog+ -rw------- 1 pgsql pgsql 88 Jan 14 14:33 postgresql.auto.conf + -rw------- 1 pgsql pgsql 21821 Jan 20 15:27 postgresql.conf + -rw------- 1 pgsql pgsql 53 Feb 4 01:29 postmaster.opts + -rw------- 1 pgsql pgsql 79 Feb 4 01:29 postmaster.pid + (1 row) Time: 4.361 ms user1@[local]:5432:user1:=#