显式更新列时,PostgreSQL触发器具有相同的OLD / NEW值

时间:2015-03-17 14:25:17

标签: postgresql triggers

我有一个包含boolean列和UPDATE触发器的表。当我尝试将列值从FALSE显式更新为TRUE时,列中的值是正确的,即OLD为FALSE,NEW为TRUE。当我尝试从TRUE更改为FALSE时,OLD和NEW都将为FALSE。我正在使用NOTIFY来检查触发器内的这些值。

有没有人经历过这种奇怪的行为?

下面是一些触发函数,我认为无关的业务逻辑被省略了:

CREATE OR REPLACE FUNCTION locker_before_state_update()
RETURNS TRIGGER
AS $$
DECLARE 
    l_reservation_id INT;
BEGIN
    -- for debugging
    PERFORM pg_notify('locker_is_alive_update', 'N' || NEW);
    PERFORM pg_notify('locker_is_alive_update', 'O' || OLD);

    -- this check will fail when update from TRUE to FALSE
    IF (NEW.state = OLD.state) AND (OLD.is_alive <> NEW.is_alive) THEN
        PERFORM pg_notify('locker_is_alive_update', NEW.id || ',' || NEW.is_alive);
        RETURN NULL;
    END IF;

    ...

RETURN NEW;
END
$$ LANGUAGE plpgsql;

CREATE TRIGGER locker_before_state_update_trigger BEFORE UPDATE ON locker FOR EACH ROW EXECUTE PROCEDURE locker_before_state_update();

1 个答案:

答案 0 :(得分:1)

您应该会遇到奇怪的行为,因为您在if语句中返回NULL。实际上发生的事情是更新根本没有完成。我通过将RETURN NULL替换为RETURN NEW来测试它,它按预期工作。 if-part:

IF (NEW.state = OLD.state) AND (OLD.is_alive <> NEW.is_alive) THEN
    PERFORM pg_notify('locker_is_alive_update', NEW.id || ',' || NEW.is_alive || ',' || OLD.is_alive);
    RETURN NEW;
END IF;