#postgresql
#postgresql
Вопрос:
В качестве школьной работы мы должны создать таблицу, которая регистрирует все операции, выполняемые пользователями в другой таблице. Чтобы быть более понятным, скажем, у меня есть table1 и logtable, table1 может содержать любую информацию (имена, идентификаторы, задания и т. Д.), logtable содержит информацию о том, кто что делал, когда в table1. Используя функцию и триггер, мне удалось сделать так, чтобы операции ВСТАВКИ, УДАЛЕНИЯ и ОБНОВЛЕНИЯ регистрировались в таблице журналов, но мы также должны вести журнал выборок. Чтобы быть более конкретным в отношении выбора, в представлении, если вы выполняете ВЫБОР, предполагается, что это должно быть зарегистрировано в logtable через INSERT, по сути, в logtable должна быть новая строка с информацией, сообщающей, что кто-то сделал ВЫБОР. Моя проблема в том, что я не могу придумать какой-либо способ добиться этого, поскольку SELECTs не может использовать триггеры и, в свою очередь, не может использовать функции, а правила не позволяют выполнять две разные операции. Единственное, что было близко, это использовать журналы запросов, однако, поскольку база данных принадлежит школе, а не мне, я не могу их использовать.
Вот примерный пример того, с чем я работаю (на самом деле tstamp имеет часы, минуты и тому подобное):
id operation hid tablename who tstamp val_new val_old
x INSERT x table1 name YYYY-MM-DD newValues previousValues
Это работает так, как задумано, но мне также нужно приступить к работе (примечание: значения val_new и old в этом случае являются пустыми или нет, не имеет значения):
id operation hid tablename who tstamp val_new val_old
x SELECT x table1 name YYYY-MM-DD NULL previousValues
Приветствуется любая помощь.
Комментарии:
1. если вы уже создали представление для данных table1, вы можете использовать правило просмотра таким образом:
CREATE RULE "_RETURN" AS ON SELECT TO view1 DO INSTEAD ( SELECT * FROM select_with_log(); );
2. Как
select_with_log()
узнать, какой идентификатор был возвращен?SELECT * from view where id = x;
3. ВСТАВИТЬ … ВОЗВРАЩАЕМЫЙ идентификатор;
4. ? Как
INSERT
узнать, какую строку вставить?5. @clamp Я предположил, что идентификатор в таблице журналов является серийным, а не выбранным идентификатором…
Ответ №1:
Вот пример:
CREATE TABLE public.test (id integer PRIMARY KEY, value integer);
INSERT INTO test VALUES (1,42),(2,13);
CREATE TABLE test_log(id serial primary key, dbuser varchar,datetime timestamp);
-- get_test() inserts username / timestamp into log, then returns all rows
-- of test
CREATE OR REPLACE FUNCTION get_test() RETURNS SETOF test AS '
INSERT INTO test_log (dbuser,datetime)VALUES(current_user,now());
SELECT * FROM test;'
language 'sql';
-- now a view returns the full row set of test by instead calling our function
CREATE VIEW test_v AS SELECT * FROM get_test();
SELECT * FROM test_v;
id | value
---- -------
1 | 42
2 | 13
(2 rows)
SELECT * FROM test_log;
id | dbuser | datetime
---- ---------- ----------------------------
1 | postgres | 2020-11-30 12:42:00.188341
(1 row)
Если в вашей таблице много строк и / или выборки сложны, вы не хотите использовать это представление по соображениям производительности.
Комментарии:
1. Большое вам спасибо за это. Это помогло мне заставить его работать так, как это было необходимо.