Postgresql 使用触发器更新新创建的行值
我的问题如下:我在postgresql数据库中插入或更新了一行,需要修改此行中的一个字段。但是,当我插入新行以在其他表上使用Postgresql 使用触发器更新新创建的行值,postgresql,triggers,sql-update,Postgresql,Triggers,Sql Update,我的问题如下:我在postgresql数据库中插入或更新了一行,需要修改此行中的一个字段。但是,当我插入新行以在其他表上使用JOIN进行SELECT时,我需要知道新的序列主键 我现在很沮丧,因为我在INSERT和UPDATE之后做了一个触发器来获得新的PK(kkw\u block\u id)。我通过选择获得所需的值,但之后我无法修改行中的值:在插入和更新之后,使用修改NEW.value是不可能的,如果我对行执行更新,我将进入无限循环,触发器将在触发器中调用 CREATE TRIGGER tsve
JOIN
进行SELECT
时,我需要知道新的序列主键
我现在很沮丧,因为我在INSERT和UPDATE之后做了一个触发器来获得新的PK(kkw\u block\u id
)。我通过选择
获得所需的值,但之后我无法修改行中的值:在插入和更新
之后,使用修改NEW.value是不可能的,如果我对行执行更新
,我将进入无限循环,触发器将在触发器中调用
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的默认值并将其分配到。您必须将现有触发器从“之后”更改为“之前”
您可以按如下顺序分配PK:
NEW.kkw_block_id = nextval('your_sequence_name_here');
由于您对INSERT和DELETE使用相同的函数,因此需要检查它是否为INSERT,然后才使用sequence。我还包括检查PK是否为空。我想这就足以在更新期间不覆盖它
IF (TG_OP = 'INSERT') AND NEW.kkw_block_id IS NULL THEN
NEW.kkw_block_id = nextval('your_sequence_name_here');
END IF;
只要该触发器对每一新行都有效,就可以了,情况似乎就是这样。这将允许您修改新的,它将反映在表中保存的数据中。删除PK的默认值,并将其分配到触发器之前的。您必须将现有触发器从“之后”更改为“之前”
您可以按如下顺序分配PK:
NEW.kkw_block_id = nextval('your_sequence_name_here');
由于您对INSERT和DELETE使用相同的函数,因此需要检查它是否为INSERT,然后才使用sequence。我还包括检查PK是否为空。我想这就足以在更新期间不覆盖它
IF (TG_OP = 'INSERT') AND NEW.kkw_block_id IS NULL THEN
NEW.kkw_block_id = nextval('your_sequence_name_here');
END IF;
只要该触发器对每一新行都有效,就可以了,情况似乎就是这样。这将允许您修改新的,并将反映在表中保存的数据中。我最终得到以下解决方案。我在触发器之前做了一个。问题在于引用新行尚不存在的表的左联接。这并不理想,但在这里:
CREATE TRIGGER tsvectorupdate
BEFORE INSERT OR UPDATE
ON kkw_block
FOR EACH ROW
EXECUTE PROCEDURE kkw_search_trigger();
CREATE TYPE kkw_type_record_type AS (typ_abr TEXT, typ_desc_en TEXT, typ_desc_short_en TEXT);
CREATE TYPE kkw_record_type AS (kkw_name_en TEXT);
CREATE OR REPLACE FUNCTION kkw_search_trigger()
RETURNS trigger AS
$BODY$
DECLARE kkw_rec kkw_record_type;
DECLARE kkw_typ_rec kkw_type_record_type;
DECLARE vector_en TEXT;
BEGIN
--- make a individual select instead of LEFT JOIN
SELECT kkw_name_en INTO kkw_rec.kkw_name_en
FROM kkw
WHERE kkw.kkw_id = NEW.kkw_id;
--- make a individual select instead of LEFT JOIN
SELECT typ_abr, typ_desc_en, typ_desc_short_en INTO kkw_typ_rec.typ_abr, kkw_typ_rec.typ_desc_en, kkw_typ_rec.typ_desc_short_en
FROM kkw_typ
WHERE kkw_typ.kkw_typ_id = NEW.kkw_typ_id;
vector_en := coalesce(NEW.modell_en, '') || ', ' || coalesce(NEW.bezeichnung_en,'') || ', ' || coalesce(kkw_rec.kkw_name_en,'') || ', ' || coalesce(kkw_typ_rec.typ_abr,'') || ', ' || coalesce(kkw_typ_rec.typ_desc_en,'') || ', ' || coalesce(kkw_typ_rec.typ_desc_short_en,'');
NEW.search_vector_en := to_tsvector('english', vector_en);
RETURN NEW;
END
$BODY$
我最终得到以下解决方案。我在触发器之前做了一个。问题在于引用新行尚不存在的表的左联接。这并不理想,但在这里:
CREATE TRIGGER tsvectorupdate
BEFORE INSERT OR UPDATE
ON kkw_block
FOR EACH ROW
EXECUTE PROCEDURE kkw_search_trigger();
CREATE TYPE kkw_type_record_type AS (typ_abr TEXT, typ_desc_en TEXT, typ_desc_short_en TEXT);
CREATE TYPE kkw_record_type AS (kkw_name_en TEXT);
CREATE OR REPLACE FUNCTION kkw_search_trigger()
RETURNS trigger AS
$BODY$
DECLARE kkw_rec kkw_record_type;
DECLARE kkw_typ_rec kkw_type_record_type;
DECLARE vector_en TEXT;
BEGIN
--- make a individual select instead of LEFT JOIN
SELECT kkw_name_en INTO kkw_rec.kkw_name_en
FROM kkw
WHERE kkw.kkw_id = NEW.kkw_id;
--- make a individual select instead of LEFT JOIN
SELECT typ_abr, typ_desc_en, typ_desc_short_en INTO kkw_typ_rec.typ_abr, kkw_typ_rec.typ_desc_en, kkw_typ_rec.typ_desc_short_en
FROM kkw_typ
WHERE kkw_typ.kkw_typ_id = NEW.kkw_typ_id;
vector_en := coalesce(NEW.modell_en, '') || ', ' || coalesce(NEW.bezeichnung_en,'') || ', ' || coalesce(kkw_rec.kkw_name_en,'') || ', ' || coalesce(kkw_typ_rec.typ_abr,'') || ', ' || coalesce(kkw_typ_rec.typ_desc_en,'') || ', ' || coalesce(kkw_typ_rec.typ_desc_short_en,'');
NEW.search_vector_en := to_tsvector('english', vector_en);
RETURN NEW;
END
$BODY$