Динамически получать имена столбцов, используя старые триггеры - PullRequest
1 голос
/ 24 сентября 2019

Я хочу написать общую триггерную функцию (процедура Postgres).Существует много основных таблиц, таких как TableA, TableB и т. Д., И соответствующие им таблицы аудита TableA_Audit, TableB_Audit соответственно.Структура приведена ниже.

TableA и TableA_Audit имеют столбцы a integer, ab integer.

TableB и TableB_Audit имеют столбцы ba integer.

Аналогично, может быть много основных таблицвместе с их таблицами аудита.

Требуется, чтобы любая основная таблица обновлялась, а затем ее записи должны быть вставлены в соответствующую таблицу аудита.

например: - Если в TableA есть записи, подобные этой

                ---------------------
                |     **TableA**   |
                ---------------------
                |aa      | ab       |
                |--------|----------|
                |    5   |  10      |
                ---------------------        

, а затем я пишу обновление, например

update TableA set aa = aa + 15,

тогда старые значения для TableA должны быть вставлены в таблицу TableA_Audit, как показано ниже

TableA_audit содержит: -

                ---------------------
                |  **TableA_Audit** |
                ---------------------
                |aa      | ab       |
                |--------|----------|
                |    5   |  10      |
                ---------------------  

Чтобы облегчить описанный выше сценарий, я написал обобщенную функцию, называемую insert_in_audit.Всякий раз, когда происходит обновление в любой из основных таблиц, должна вызываться функция insert_in_audit.Функция должна достигать следующего: -

  1. Динамически вставлять записи в соответствующую таблицу аудита с использованием главной таблицы.Если есть обновление в таблице B, то записи должны быть вставлены только в TableB_Audit.

До сих пор, что я могу сделать.У меня есть имена всех столбцов главной таблицы, где произошло обновление.Например: для запроса - обновить TableA, установить aa = aa + 15, я могу получить все имена столбцов в TableA в массиве varchar.

column_names varchar []: = '{"aa", "ab "} ';

Мой вопрос заключается в том, как получить старые значения столбцов aa и ab.Я попытался сделать так:

foreach i in array  column_names
loop
 raise notice '%', old.i;
end loop;

Но вышеописанное дало мне ошибку: - запись "old" не имеет поля "i".Может ли кто-нибудь помочь мне получить старые ценности.

1 Ответ

0 голосов
/ 26 сентября 2019

Вот пример кода, как вы можете динамически извлекать значения из OLD в PL / pgSQL:

CREATE FUNCTION dynamic_col() RETURNS trigger
   LANGUAGE plpgsql AS
$$DECLARE
   v_col name;
   v_val text;
BEGIN
   FOREACH v_col IN ARRAY TG_ARGV
   LOOP
      EXECUTE format('SELECT (($1).%I)::text', v_col)
         USING OLD
         INTO v_val;
      RAISE NOTICE 'OLD.% = %', v_col, v_val;
   END LOOP;

   RETURN OLD;
END;$$;

CREATE TABLE trigtest (
   id integer,
   val text
);

INSERT INTO trigtest VALUES
   (1, 'one'), (2, 'two');

CREATE TRIGGER dynamic_col AFTER DELETE ON trigtest
   FOR EACH ROW EXECUTE FUNCTION dynamic_col('id', 'val');

DELETE FROM trigtest WHERE id = 1;

NOTICE:  OLD.id = 1
NOTICE:  OLD.val = one
...