Postgresql

在 postgresql 中執行系統命令

  • September 21, 2021

我的要求是在觸發器執行時執行系統命令,如 (ls) 或 C 程序。有沒有辦法創建一個觸發函式來解決這個問題。

您可以輕鬆地執行*@a_horse_with_no_name*在他的評論中建議的操作。但也有一種有趣的方法可以做到這一點,使用 PL/pgSQL 作為函式語言。

這使用了COPYPostgreSQL 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_data

SELECT 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:=#

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