如果实体/外键更新,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_on 在 entry
更新时得到更新。
以下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.
我有一个 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_on 在 entry
更新时得到更新。
以下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.