[英]POSTGRESQL pl/pgsql trigger function returns null on insert
我有一個像這樣的pg表:
CREATE TABLE order_status_history (
order_id integer NOT NULL,
status character varying NOT NULL,
sequence integer DEFAULT 1 NOT NULL,
date_status timestamp with time zone DEFAULT now() NOT NULL,
record_state character varying(12) DEFAULT 'ACTIVE'::character varying NOT NULL
);
在order_id和sequence上使用復合PK。 本質上,對於每個單獨的order_id,狀態列都是從1開始的自動遞增值。 因此,如果order_id 2已經有兩行,則序列應為1和2,對於新行,序列應為3。我試圖在插入之前使用觸發器來實現此行為,但是當我嘗試為新的order_id插入第一行(即觸發器在插入之前不必更改行),我遇到了PG錯誤。 說它不能將NULL插入序列。 我看不到觸發函數將如何返回NULL,但是我的pl / sql不好,所以我確定它很簡單...下面的觸發函數,謝謝。
DECLARE
seq_no INTEGER;
BEGIN
SELECT INTO seq_no MAX(sequence) FROM rar.order_status_history WHERE order_id = NEW.order_id;
IF FOUND THEN
NEW.sequence := seq_no + 1;
END IF;
RETURN NEW;
END;
如果order_status_history中沒有該order_id的內容,則MAX(sequence)
將為null。 使用COALESCE(MAX(sequence),0)
使其默認為1。
您可以簡單地寫:
NEW.sequence := (SELECT COALESCE(MAX(sequence),0) FROM /* etc.. */) + 1;
在執行此操作之前,您還應該確實將訂單行鎖定為獨占模式,以允許它與同時插入同一訂單歷史記錄的多個交易一起使用。 那是:
SELECT 1 FROM orders WHERE orders.order_id = NEW.order_id FOR UPDATE;
max(sequence)
始終為FOUND
,但如果沒有數據,則可以為NULL
。 在這種情況下,您的NEW.sequence := seq_no + 1
使其仍然為NULL
。 IF seq_no IS NOT NULL
聽起來更合適。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.