Postgresql
如何防止觸發器覆蓋顯式設置的值?
我試過這個但沒有用,因為
NEW.updated
從來沒有NULL
(我想NEW
除了更新語句中的值之外,還填充了目前行中的值?):create temp table test ( created TIMESTAMPTZ NOT NULL DEFAULT now(), updated TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE FUNCTION update_timestamp() RETURNS TRIGGER AS $$ BEGIN IF NEW.updated IS NOT NULL THEN NEW.updated := now(); END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER asdf BEFORE UPDATE ON test FOR EACH ROW EXECUTE PROCEDURE update_timestamp();
NEW.updated := now();
僅當updated
未在更新語句中明確設置時,如何才能設置它?updated
這樣當我想手動設置列時觸發器不會覆蓋我(例如updated=updated
)。
OLD
包含表中的目前值,NEW
這些值就像它們在UPDATE
.如果
NEW.updated IS DISTINCT FROM OLD.updated
,則很明顯,該語句(或先前的觸發器)updated
必須已更改。UPDATE
如果
NEW.updated IS NOT DISTINCT FROM OLD.updated
,您無法知道語句中是否updated
指定了-可能已設置為與之前相同的值。UPDATE``UPDATE``updated
所以你能得到的最好的就是
IF NEW.updated IS NOT DISTINCT FROM OLD.updated THEN NEW.updated := current_timestamp; END IF;
如果你有類似的東西,這不會做你想做的事
SET updated = updated
,但沒有補救辦法。
一個笨拙的解決方案,直到出現更好的東西。像這樣使用它:如果你的意思是
updated=updated
,那麼你寫updated=NULL
。create temp table test ( created TIMESTAMPTZ NOT NULL DEFAULT now(), updated TIMESTAMPTZ ); CREATE OR REPLACE FUNCTION update_timestamp() RETURNS TRIGGER AS $$ BEGIN IF NEW.updated IS NULL THEN IF OLD.updated IS NULL THEN -- first time updating this record NEW.updated := now(); ELSE -- use updated=NULL as workaround for updated=updated NEW.updated := OLD.updated; END IF; ELSE NEW.updated := now(); END IF; RETURN NEW; END; $$ LANGUAGE plpgsql;