所以有几件事。对于这种类型的问题,访问测试表格定义肯定有帮助。我嘲笑了我期望的桌子设计。此外,包含“所需行为”(即,是否打算始终将状态设置为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'中移除'因为它不是必需的。 –