我有一個列舉('not created', 'in creation', 'created', 'update', 'rejective')。
和一個PostgreSQL中的觸發器,它擁有一些邏輯,用于在INSERT或UPDATE時改變記錄的狀態:
CREATE OR REPLACE FUNCTION Set_status()
RETURNS trigger AS
$BODY$
BEGIN
如果TG_OP ILIKE 'UPDATE' THEN --這一行是在Pavel Stehule的回答之后添加的。
如果(NEW.field1 IS NULL) THEN NULL
NEW.status = 'not created'。
ELSEIF (NEW.field1 IS NOT NULL) THEN
如果OLD.status IN ('not created')
THEN
NEW.status = 'created'; -- point 1.
ELSEIF OLD.status IN ('created', 'uped', 'refed') --第2點。
AND NEW.status NOT IN ('not created')
THEN
NEW.status = '更新'。
ELSEIF NEW. status NOT IN ('not created', '創建'/span>, '更新'/span>, '拒絕'/span>)
THEN[/span
NEW.status = 'in creation';
ELSE
NEW.status = 'not created';
END IF;
END IF;
END IF; -- 這一行是在Pavel Stehule的回答之后添加的。
RETURN NEW。
END; END
$BODY$
LANGUAGE 'plpgsql'/span>;
創建 TRIGGER update_status_biut
在INSERT OR UPDATE之前
ON table
FOR EACH ROW
EXECUTE PROCEDURE set_status();
一切作業正常,除了當狀態以'not created'值開始時(這是新記錄的默認值),它在UPDATE或INSERT時直接切換到'uped',而它在第一次處理記錄時應該停留在'created'。
對我來說,這聽起來像是我放置"--第1點 "的地方,NEW.status在這里取值'created',這是正確的,但是在下一個ELSEIF塊,它重新使用該值作為'OLD.status'(?),因此驗證條件,這使得它切換到'更新'。
我還通過嘗試從"--點2 "的串列中移除'created'值來驗證了這一點。在這種情況下,在UPDATE/INSERT之后,狀態一直保持在'created'上。
如何避免這種奇怪的行為,并在 if 塊中保留第一個已經滿足的值(在這種情況下,'created'),并 "傳遞 "其他的(以下)值?
版本資訊(Dockerized PostgreSQL):
# psql --version
psql (PostgreSQL) 13.3 (Debian 13.3-1.__span>pgdg100 1)
編輯:我找到了我的麻煩源頭......
。uj5u.com熱心網友回復:
NEW和OLD變數的行為取決于使用的PostgreSQL版本。NEW對于INSERT或UPDATE事件有很好的定義。OLD對于UPDATE和DELETE有明確的定義。當你在INSERT事件中使用OLD時,那么你在舊的Postgreses上得到一個例外,而今天你將得到NULL。
你的設計并不理想。在這種情況下,你應該使用隱式變數
。
來源。https://www.postgresql.org/docs/13/sql-createtrigger.html
通過使用這個選項,觸發器只在更新指定的列時觸發,這就避免了NEW.Not_specified_field
的 "神器"(好吧,它并不是真正的神器,但當你第一次遇到這種行為時,它是超級奇怪的)。 not_specified_field(在部分 UPDATE 請求期間),它即時(即'on-the-fly',即在觸發函式中使用之前)從 DB 中分配相應的 OLD 值(如果有必要檢查傳入的空值,你可能不希望如此!)。
這樣,我就能夠放棄我在觸發器函式中所做的混亂的檢查。現在它變得更干凈了。
這篇帖子也幫助我解決了這個問題。https://stackoverflow.com/a/8762116/6630397
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/329414.html
標籤:
上一篇:使用邏輯運算子比較多個字串在C語言編程中不能正常作業
下一篇:一次性檢查大量變數的真實性


