Postgres функция для создания ошибки выброса таблицы аудита. У INSERT больше выражений, чем у целевых столбцов. - PullRequest
0 голосов
/ 09 марта 2020

У меня есть таблица, содержащая идентификатор, статус и дату добавления. Идентификатор и дата добавлены по умолчанию к целочисленным значениям nextval и current_timestamp соответственно. Затем у меня есть триггер, который вызывает функцию вставки, обновления или удаления. В этой функции все, что она делает, - это резервное копирование и отслеживание изменений в таблице состояния. Этот метод успешно работал, когда в таблицу было добавлено более одного поля. С таблицей состояния я только добавляю поле состояния и позволяю БД позаботиться о двух других полях, и я получаю сообщение об ошибке. Похоже, что мне может понадобиться сделать что-то другое в функции? Я добавляю данные в эти таблицы, используя python для автоматизации, и попытался добавить запись в таблицу вручную с той же самой ошибкой.

Error while fetching data from PostgreSQL INSERT has more expressions than target columns
LINE 2:        (TG_OP, NEW.*)
                       ^
QUERY:  INSERT INTO api_audit.d_status_list (id, status, dateadded) VALUES
       (TG_OP, NEW.*)
CONTEXT:  PL/pgSQL function api_input.d_status_list_func() line 4 at SQL statement

Код функции:

create function d_status_list_func() returns trigger
    language plpgsql
as
$$
BEGIN
IF TG_OP = 'INSERT' THEN
  INSERT INTO api_audit.d_status_list (id, status, dateadded) VALUES
       (TG_OP, NEW.*);
  RETURN NEW;
ELSIF TG_OP = 'UPDATE' THEN
   INSERT INTO api_audit.d_status_list (id, status, dateadded) VALUES
        (TG_OP, NEW.*);
   RETURN NEW;
ELSIF TG_OP = 'DELETE' THEN
   INSERT INTO api_audit.d_status_list (id, status, dateadded) VALUES
        (TG_OP, OLD.*);
   RETURN OLD;
END IF;
END;
$$;

alter function d_status_list_func() owner to blahblah;

Любая помощь приветствуется.

1 Ответ

2 голосов
/ 09 марта 2020

Вставка не удалась, потому что вы объявляете три столбца для insert (id, status, dateadded), но вы даете ему 4 значения: операция (вставка, обновление, удаление), затем 3 исходных столбца.

Предположительно, ваша таблица аудита имеет (или должна иметь) столбец, в котором хранится выполняемая операция.

Если это так, вы должны указать этот столбец в операторе insert:

INSERT INTO api_audit.d_status_list (operation, id, status, dateadded) 
VALUES (TG_OP, NEW.*);

Вообще говоря, хорошей практикой является избегать * и явно перечислять столбцы, что упрощает отслеживание, когда они go ошибочны, поэтому:

INSERT INTO api_audit.d_status_list (operation, id, status, dateadded) 
VALUES (TG_OP, NEW.id, NEW.status, NEW.dateadded);
...