触发自引用 table
Trigger on self-referenced table
我有一个像这样的 invoices
table :
CREATE TABLE invoices (
idinvoice SERIAL PRIMARY KEY
,idclient INTEGER REFERENCES clients(idclient)
-- other fields here
);
和一个 invoiceitems
table :
CREATE TABLE invoiceitems (
idinvoiceitem SERIAL PRIMARY KEY
,idinvoice INTEGER REFERENCES invoices(idinvoice)
,amount NUMERIC(15,2)
,sortorder INTEGER DEFAULT 10
);
我的问题是 sortorder
字段:每次插入或更新发票项目时,我都希望使用这样的查询重新计算同一张发票的所有项目的 sortorder
s :
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;
这样,每次添加新项目时,都会编号为 10+最后一项,如果我决定通过手动设置值来更改项目的排序顺序,所有 sortorder
s 将以 10 为增量重新计算:
id | sortorder
---+----------
1 | 10
2 | 20
3 | 30
4 | 40 ← I change this to 25
然后查询后得到:
id | sortorder
---+----------
1 | 10
2 | 20
4 | 30
3 | 40
我想把它放在触发器中。问题是第 4 项将被触发器更新(因此再次调用触发器),我将得到某种无休止的递归。
有办法吗?例如,设置一些 semaphore 以防止在触发器本身发生更新时调用触发器?或者可能是显式锁定?
(使用 PostgreSQL 11+)
我有一个像这样的 invoices
table :
CREATE TABLE invoices (
idinvoice SERIAL PRIMARY KEY
,idclient INTEGER REFERENCES clients(idclient)
-- other fields here
);
和一个 invoiceitems
table :
CREATE TABLE invoiceitems (
idinvoiceitem SERIAL PRIMARY KEY
,idinvoice INTEGER REFERENCES invoices(idinvoice)
,amount NUMERIC(15,2)
,sortorder INTEGER DEFAULT 10
);
我的问题是 sortorder
字段:每次插入或更新发票项目时,我都希望使用这样的查询重新计算同一张发票的所有项目的 sortorder
s :
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;
这样,每次添加新项目时,都会编号为 10+最后一项,如果我决定通过手动设置值来更改项目的排序顺序,所有 sortorder
s 将以 10 为增量重新计算:
id | sortorder
---+----------
1 | 10
2 | 20
3 | 30
4 | 40 ← I change this to 25
然后查询后得到:
id | sortorder
---+----------
1 | 10
2 | 20
4 | 30
3 | 40
我想把它放在触发器中。问题是第 4 项将被触发器更新(因此再次调用触发器),我将得到某种无休止的递归。
有办法吗?例如,设置一些 semaphore 以防止在触发器本身发生更新时调用触发器?或者可能是显式锁定?
(使用 PostgreSQL 11+)