Mon exigence est d'exécuter une commande système comme (ls) ou un programme C lorsqu'un déclencheur s'exécute. Existe-t-il un moyen de créer une fonction de déclenchement pour résoudre ce problème.
Vous pouvez facilement faire ce que @ a_horse_with_no_name suggère dans son commentaire. Mais il existe également un moyen intéressant de le faire, en utilisant PL/pgSQL comme langage de fonction.
Cela utilise une fonctionnalité de la commande COPY
, introduite dans PostgreSQL 9.3. Il peut désormais prendre une commande comme cible/source, exactement là où vous utiliseriez un nom de fichier ou STDIN/STDOUT dans des cas normaux:
COPY table_name [ ( column_name [, ...] ) ] FROM { 'filename' | PROGRAM 'command' | STDIN } [ [ WITH ] ( option [, ...] ) ]
Évidemment, vous avez besoin d'une table pour mettre la sortie, mais vous pouvez l'ignorer, si vous le souhaitez.
Voir un petit exemple:
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
Remarque: la fonction doit s'exécuter avec les droits de superutilisateur - c'est-à-dire soit faire le INSERT
en tant que superutilisateur, soit définir la fonction avec SECURITY DEFINER
. Dans tous les autres cas, vous obtiendrez une erreur:
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.
Si vous avez juste besoin de regarder quelque chose par rapport à $PGDATA
vous pouvez utiliser pg_ls_data
SELECT pg_ls_dir('pg_xlog');
Sinon, une simple fonction comme celle-ci:
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;
Vous donnera une sortie comme celle-ci:
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:=#