如果实体/外键更新,postgres 更新父级

postgres update parent if entity / foreign key updates

我有一个 table recipes 每个 recipe 可以有多个 entries.

CREATE TABLE IF NOT EXISTS "recipes" (
    "ident" SERIAL PRIMARY KEY,
    "identifier" TEXT NOT NULL UNIQUE,
    "modified_on" TIMESTAMP WITH TIME ZONE DEFAULT NULL
);

CREATE TABLE IF NOT EXISTS "entries" (
    "ident" SERIAL PRIMARY KEY,
    "recipe_id" INTEGER NOT NULL,
    "name" TEXT
    FOREIGN KEY ("recipe_id") REFERENCES "recipes"("ident") ON DELETE CASCADE
);

现在,当更新 recipe 时,将调用以下函数并更新我的时间戳:

CREATE OR REPLACE FUNCTION update_recipe_timestamp_proc()
RETURNS TRIGGER AS $$
BEGIN
    NEW."modified_on" = now();
    PERFORM pg_notify('notify_recipes_update', CAST(NEW.ident AS text));
    RETURN NEW;   
END;
$$ language 'plpgsql';

现在我还希望我的时间戳 modified_onentry 更新时得到更新。

以下trigger不工作。

DROP TRIGGER IF EXISTS update_recipes_timestamp_e ON entries;
CREATE TRIGGER update_recipes_timestamp_e BEFORE UPDATE ON entries FOR EACH ROW EXECUTE PROCEDURE update_recipe_timestamp_proc();

错误:记录 "NEW" 没有字段 "modified_on"

我在评论中说明了这一点,但为了完整起见,我会把它放在这里。

您当前的问题是您正在尝试设置一个不存在的字段的值。触发器中的 NEW 是您正在插入或更新的实际记录,因为它发生在 entries table 上。基于此,您可以了解为什么它们不起作用以及为什么会出现该错误。

您的问题的解决方案是删除该行 NEW."modified_on" = now(); 并将其替换为将更新 recipe table.[=20 的 UPDATE 语句=]

您的最终触发代码应如下所示:

CREATE OR REPLACE FUNCTION update_recipe_timestamp_proc()
RETURNS TRIGGER AS $$
BEGIN
    UPDATE recipe SET modified_on = now() WHERE ident = NOW.recipe_id;
    PERFORM pg_notify('notify_recipes_update', CAST(NEW.ident AS text));
    RETURN NEW;   
END;
$$ language 'plpgsql';

您在 entries 中 inserting/updating 的记录具有您在 UPDATE 语句中使用的字段 recipe_id 以确保您更新 UPDATE 中的正确记录=15=] table.