簡體   English   中英

POSTGRESQL pl / pgsql觸發函數在插入時返回null

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM