I have an invoices
table like this :
CREATE TABLE invoices (
idinvoice SERIAL PRIMARY KEY
,idclient INTEGER REFERENCES clients(idclient)
-- other fields here
);
and an invoiceitems
table :
CREATE TABLE invoiceitems (
idinvoiceitem SERIAL PRIMARY KEY
,idinvoice INTEGER REFERENCES invoices(idinvoice)
,amount NUMERIC(15,2)
,sortorder INTEGER DEFAULT 10
);
My problem is with the sortorder
field : every time I insert or update an invoiceitem, I want the sortorder
s of all items of the same invoice to be recalculated with a query like this :
WITH pre AS (
SELECT idinvoiceitem,10*ROW_NUMBER() OVER (ORDER BY sortorder,idinvoiceitem) AS rownum
FROM invoiceitems
WHERE idinvoice=xx
ORDER BY sortorder,idinvoiceitem
)
UPDATE invoiceitems di
SET sortorder=rownum
FROM pre p
WHERE p.idinvoiceitem=di.idinvoiceitem;
That way, every time a new item is added, it will be numbered 10+last item, and if I decide to change the sort order of the item by manually setting a value, all the sortorder
s will be recalculated with a 10 increment :
id | sortorder
---+----------
1 | 10
2 | 20
3 | 30
4 | 40 ← I change this to 25
Then after the query, I will get :
id | sortorder
---+----------
1 | 10
2 | 20
4 | 30
3 | 40
I would like to have this in a trigger. The problem is that item #4 will be UPDATEd by the trigger (thus calling the trigger again) and I will get some kind of endless recursion.
Is there a way to do this ? For example, set some semaphore that would prevent the trigger from being called when the UPDATE occurs within the trigger itself ? Or maybe an explicit LOCK ?
(using PostgreSQL 11+)