所以有幾件事。對於這種類型的問題,訪問測試表格定義肯定有幫助。我嘲笑了我期望的桌子設計。此外,包含「所需行爲」(即,是否打算始終將狀態設置爲100?無論table_b發生什麼情況)都很有幫助。此外,update
聲明必然會遇到整個table_a
,這就是爲什麼您需要唯一約束才能獲得唯一記錄。如果您錯誤地將狀態設置爲100,那麼它應該是SET status = new.status
,這將是一個不同的問題(但可能看起來更新是「擊中整個表」,請參閱下面的示例 - 特別是section_id=3
)。
希望以下說明準確的行爲。我懷疑你的觸發器應該設置status=new.status
:
CREATE TABLE table_a
(
section_id serial
, status integer
, CONSTRAINT pk_table_a PRIMARY KEY (section_id)
);
CREATE TABLE table_b
(
id serial
, section_id integer
, status integer
, CONSTRAINT pk_table_b_aiu PRIMARY KEY (id)
)
;
CREATE OR REPLACE FUNCTION table_b_aiu()
RETURNS trigger AS
$BODY$
BEGIN
UPDATE table_a a
SET status = 100 -- intentional??
WHERE (new.status = 100 or new.status = 200)
AND a.section_id = new.section_id;
RETURN new;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE TRIGGER table_b_aiu
AFTER INSERT OR UPDATE
ON table_b
FOR EACH ROW
WHEN (((new.status = 100) OR (new.status = 200)))
EXECUTE PROCEDURE table_b_aiu();
INSERT INTO table_a (section_id, status)
values (1,100)
, (2,200)
, (3,201)
, (4, 202)
returning *;
| section_id | status |
| 1 | 100 |
| 2 | 200 |
| 3 | 201 |
| 4 | 202 |
INSERT INTO table_b (section_id, status)
values (1,101), (2,100), (3,200), (4,201)
returning *;
| id | section_id | status |
| 1 | 1 | 101 |
| 2 | 2 | 100 |
| 3 | 3 | 200 |
| 4 | 4 | 201 |
select *
from table_a;
| section_id | status |
| 1 | 100 |
| 4 | 202 |
| 2 | 100 |
| 3 | 100 |
注:new.status in (100,200)
是多餘的,但我想你想成爲安全(萬一有人曾是建立一個觸發沒有when
聲明
。
我的建議:如果你想對錶本身的狀態選項限制二百分之百,我建議建立一個外鍵的status
表,只有具有這些選項
是'section_id'獨具一格。行的標識符?對th的定義有幫助還有問題的表格。 – cole
@ C.Arendt section_id是table_a的主鍵,但不是table_b的 – Luffydude
您是什麼意思的觸發器參數?像這樣:'EXECUTE PROCEDURE table_b_aiu(new.section_id);'? 您有權訪問該行而不將其作爲參數傳遞。您可以簡單地執行'where a.section_id = new.section_id'並從'table_b'中移除'因爲它不是必需的。 –