Yêu cầu của tôi là thực thi một lệnh hệ thống như (ls) hoặc chương trình C khi kích hoạt thực thi. Có cách nào để tạo một chức năng kích hoạt để giải quyết vấn đề này.
Yêu cầu của tôi là thực thi một lệnh hệ thống như (ls) hoặc chương trình C khi kích hoạt thực thi. Có cách nào để tạo một chức năng kích hoạt để giải quyết vấn đề này.
Câu trả lời:
Bạn có thể dễ dàng làm những gì @a_horse_with_no_name gợi ý trong bình luận của mình. Nhưng cũng có một cách thú vị để làm điều đó, sử dụng PL / pgSQL làm ngôn ngữ hàm.
Điều này sử dụng một tính năng của COPY
lệnh, được giới thiệu trong PostgreSQL 9.3. Giờ đây, nó có thể nhận lệnh làm đích / nguồn, chính xác là nơi bạn sử dụng tên tệp hoặc STDIN / STDOUT trong các trường hợp thông thường:
COPY table_name [ ( column_name [, ...] ) ] FROM { 'filename' | PROGRAM 'command' | STDIN } [ [ WITH ] ( option [, ...] ) ]
Rõ ràng, bạn cần một bảng để đặt đầu ra, nhưng bạn có thể bỏ qua nó, nếu bạn muốn.
Xem một ví dụ nhỏ:
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
Lưu ý: chức năng cần phải chạy với quyền superuser - nghĩa là, thực hiện INSERT
như một siêu người dùng hoặc xác định chức năng với SECURITY DEFINER
. Trong mọi trường hợp khác, bạn sẽ gặp lỗi:
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.
TO PROGRAM
phần này yêu cầu một chuỗi ký tự, vì vậy nếu bạn muốn một lệnh động, bạn phải bọc toàn bộ EXECUTE
. Xem stackoverflow.com/a/42626659/5419599 .
Nếu bạn chỉ cần nhìn vào một cái gì đó liên quan đến $PGDATA
bạn có thể sử dụng pg_ls_data
SELECT pg_ls_dir('pg_xlog');
Mặt khác, một chức năng đơn giản như thế này:
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;
Sẽ cung cấp cho bạn đầu ra như thế này:
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:=#
SECURITY DEFINER
).