I have a pg table like this:
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
);
with composite PK on order_id and sequence.
Essentially the status column is an auto-increment value starting at 1, for each individual order_id. So, if order_id 2 already has two rows, the sequences would be 1 and 2, and for a new row, the sequence should be 3.
I’m trying to use a trigger to implement this behaviour before insert, but when I try to insert the first row for a new order_id (i.e. trigger doesn’t have to change the row prior to insert), I’m getting an error for PG. saying that it cannot insert NULL into sequence. I can’t see how my trigger function would be returning NULL, but my pl/sql is not great so i’m sure it’s something simple… Trigger function below, thanks.
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;
If there is nothing in order_status_history for that order_id, then
MAX(sequence)will be null. UseCOALESCE(MAX(sequence),0)to make it default to 1.You could simply write:
You should really be locking the order row in exclusive mode before you do this as well, to allow this to work with multiple transactions concurrently inserting into the history for the same order. That is: