我的问题如下:我在 postgresql 数据库中插入或更新一行,需要修改该行中的一个字段。但是当我插入一个新行以在其他表上使用 JOIN
制作 SELECT
时,我需要知道新的串行 PK。
我现在卡住了,因为我已经完成了一个AFTER INSERT AND UPDATE
触发器来获取新的 PK (kkw_block_id
)。我通过 SELECT
获得了我需要的值,但之后我无法修改行中的值:修改 NEW.value is not possible with AFTER INSERT AND UPDATE
如果我在行上执行 UPDATE
,我会进入无限循环,触发器中会调用触发器...
CREATE TRIGGER tsvectorupdate
AFTER INSERT OR UPDATE
ON kkw_block
FOR EACH ROW
EXECUTE PROCEDURE kkw_search_trigger();
CREATE OR REPLACE FUNCTION kkw_search_trigger()
RETURNS trigger AS
$BODY$
DECLARE vector_en TEXT;
DECLARE vector_fr TEXT;
DECLARE vector_de TEXT;
BEGIN
-- I need the new serial PK(kkw_id) in the following section.
SELECT coalesce(modell_en, '') || ', ' || coalesce(bezeichnung_en,'') || ', ' || coalesce(kkw.kkw_name_en,'') || ', ' || coalesce(kkw_typ.typ_abr,'') || ', ' || coalesce(kkw_typ.typ_desc_en,'') || ', ' || coalesce(kkw_typ.typ_desc_short_en,'') INTO vector_en
FROM kkw_block
LEFT JOIN kkw ON NEW.kkw_id = kkw.kkw_id
LEFT JOIN kkw_typ ON NEW.kkw_typ_id = kkw_typ.kkw_typ_id
WHERE kkw_block_id = NEW.kkw_block_id;
-- I need to update a field of the newly created or updated row.
NEW.search_vector_en := to_tsvector('english', 'new test vector'); --- This doesn't work with 'AFTER UPDATE' trigger.
RETURN NULL;
END
$BODY$
有什么想法吗?
最佳答案
为您的 PK 删除默认值并在您的 BEFORE 触发器中分配它。您必须将现有的触发器从 AFTER 更改为 BEFORE。
您可以像这样从序列中分配 PK:
NEW.kkw_block_id = nextval('your_sequence_name_here');
由于您对 INSERT 和 DELETE 使用相同的函数,因此您需要检查它是否是 INSERT,然后才使用序列。我还包括检查 PK 是否为空。我想仅此一项就足以在更新期间不覆盖它。
IF (TG_OP = 'INSERT') AND NEW.kkw_block_id IS NULL THEN
NEW.kkw_block_id = nextval('your_sequence_name_here');
END IF;
只要这个触发器对每个新行都有效,就可以了,似乎是这样。这将让您修改 NEW,它将反射(reflect)在表中保存的数据中。
关于postgresql - 使用触发器更新新创建的行值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45481445/