SQL-триггер Postgres для обновления TableA.column новым значением ПОСЛЕ ВСТАВКИ ИЛИ ОБНОВЛЕНИЯ в TableB - PullRequest
0 голосов
/ 25 сентября 2018

У меня очень простой триггер, который обновляет столбец в table_a при каждом обновлении table_b:

create or replace function trigger_update_status()
    returns trigger as 
    $body$
    begin

-- UPDATE TABLE A   
update table_a
    set a_status = new.b_status,
        date_updated = now()
    from table_b
        where table_a.serial_number = table_b.serial_number; 

    return new;

end;
$body$
language plpgsql;

create trigger "currentStatus" after update or insert on table_b
for each row 
execute procedure trigger_update_status();

Однако я получаю сообщение об ошибке, что RETURN значение отсутствует:

ERROR: control reached end of trigger procedure without RETURN

Я не понимаю, подходит ли здесь NEW, поскольку я читаю противоречивую информацию.С одной стороны, ответ здесь ( триггер Postgres после доступа к вставке NEW ) проясняет, что: "Возвращаемое значение триггера уровня строки, запущенного AFTER, или триггера уровня оператора, запущенного BEFOREили AFTER всегда игнорируется; он также может быть нулевым. Однако любой из этих типов триггеров может все же прервать всю операцию, вызвав ошибку. "

С другой стороны, мой триггер здесьпо существу совпадает с приведенным здесь (https://dba.stackexchange.com/questions/182678/postgresql-trigger-to-update-a-column-in-a-table-when-another-table-gets-inserte),, который вызывает NEW & AFTER вместе. Поэтому я не уверен, почему мой не работает. Любая помощь очень ценится!

1 Ответ

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

Будущий ответ для любого с такой же проблемой: это был второй (с аналогичным названием, поэтому я не уловил его намного позже) триггер, который назывался ПОСЛЕ этого, который вызывал проблему.Второй триггер не может RETURN NEW, потому что в этом случае не было нового значения.Я исправил это, добавив оператор IF/ELSE ко второму триггеру:

IF NEW.current_location <> OLD.current_location 
    THEN
    INSERT INTO table_x(serial_number, foo, bar)
        VALUES(OLD.serial_number, OLD.foo, old.bar);
    return new;

-- ADDED THIS LINE: 
    else return null;
END IF;

Извлеченный урок благодаря биту @sticky - если триггер работает в изолированном dbfiddle, проблема возникает из-за чего-то другого.

...