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

显式更新列时,PostgreSQL触发器具有相同的旧/新值,postgresql,triggers,Postgresql,Triggers,我有一个带有boolean列和更新触发器的表。当我尝试将列值从FALSE显式更新为TRUE时,列中的值是正确的,即旧值为FALSE,新值为TRUE。当我尝试从TRUE更改为FALSE时,新旧代码都将FALSE。我正在使用NOTIFY检查触发器中的这些值 有人经历过这种奇怪的行为吗 下面是一些触发函数,我认为不相关的业务逻辑被省略了: CREATE OR REPLACE FUNCTION locker_before_state_update() RETURNS TRIGGER AS $$ DECL

我有一个带有
boolean
列和更新触发器的表。当我尝试将列值从
FALSE
显式更新为
TRUE
时,列中的值是正确的,即旧值为
FALSE
,新值为
TRUE
。当我尝试从
TRUE
更改为
FALSE
时,新旧代码都将
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();
在更新状态之前创建或替换函数锁
返回触发器
作为$$
声明
l_预订_idint;
开始
--用于调试
执行pg|U通知('locker|U处于活动状态|U更新,'N'|新);
执行pg|U通知(“储物柜|U处于活动状态|U更新状态”、“O||旧状态”);
--当从TRUE更新为FALSE时,此检查将失败
如果(NEW.state=OLD.state)和(OLD.is\u alive NEW.is\u alive),那么
执行pg|u notify('locker|u is|u alive|u update',NEW.id | |','| NEW.is|u alive);
返回NULL;
如果结束;
...
归还新的;
结束
$$语言plpgsql;
为每行创建触发器锁存器在锁存器上更新之前的触发器在锁存器上更新之前执行过程锁存器在锁存器上更新之前的触发器;

您应该会遇到奇怪的行为,因为您在if语句中返回了
NULL
。事实上,更新根本没有完成。我通过将
returnnull
替换为
returnnew
对其进行了测试,结果与预期一样。如果部分:

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;
如果(NEW.state=OLD.state)和(OLD.is\u alive NEW.is\u alive),则
执行pg|u notify('locker|u is|u alive|u update',NEW.id | |','| NEW.is| u alive |','| OLD.is|u alive);
归还新的;
如果结束;

if语句中的条件将在任何列为
null
时失败。可能是这样吗?@a_horse_和_no_name Nope,所有列值都不是空的。