在 postgresql 中执行系统命令

moh*_*raj 10 rdbms postgresql unix

我的要求是在触发器执行时执行像 (ls) 或 C 程序这样的系统命令。有没有办法创建一个触发函数来解决这个问题。

dez*_*zso 16

您可以轻松地按照@a_horse_with_no_name在他的评论中的建议进行操作。但也有一种有趣的方法来做到这一点,使用 PL/pgSQL 作为函数语言。

这使用了COPYPostgreSQL 9.3 中引入的命令功能。它现在可以将命令作为目标/源,这正是您在正常情况下使用文件名或 STDIN/STDOUT 的地方:

COPY table_name [ ( column_name [, ...] ) ]
    FROM { 'filename' | PROGRAM 'command' | STDIN }
    [ [ WITH ] ( option [, ...] ) ]
Run Code Online (Sandbox Code Playgroud)

显然,您需要一个表格来放置输出,但如果您愿意,您可以忽略它。

看一个小例子:

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
Run Code Online (Sandbox Code Playgroud)

注意:该函数需要以超级用户权限运行——也就是说,要么以超级用户身份运行,要么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.
Run Code Online (Sandbox Code Playgroud)


Kas*_*dry 7

如果您只需要查看与$PGDATA您相关的内容,可以使用pg_ls_data

SELECT pg_ls_dir('pg_xlog');
Run Code Online (Sandbox Code Playgroud)

否则,一个简单的函数是这样的:

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;
Run Code Online (Sandbox Code Playgroud)

会给你这样的输出:

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:=#
Run Code Online (Sandbox Code Playgroud)