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

时间:2017-07-17 12:37:23

标签: postgresql npgsql

我有一个表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';

现在,我还希望每当entry更新时,我的时间戳 modified_on 都会更新。

以下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();

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

1 个答案:

答案 0 :(得分:1)

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

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

您的问题的解决方案是删除该行NEW."modified_on" = now();,而是将其替换为将更新UPDATE表的recipe语句。

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

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中插入/更新的记录包含您在recipe_id语句中使用的字段UPDATE,以确保您更新recipe中的正确记录表