创建触发器以使用子查询自动更新列
Create trigger to automatically update column with subquery
在我的应用程序中,我有几个表,lessons
和 votes
。它们的外观如下:
课程
+-------------+---------+----------------------+
| Column | Type | Modifiers |
|-------------+---------+----------------------|
| id | uuid | not null |
| votes_total | integer | not null default 0 |
+-------------+---------+----------------------+
投票
+-------------+---------+-------------+
| Column | Type | Modifiers |
|-------------+---------+-------------|
| positive | boolean | not null |
| user_id | uuid | not null |
| lesson_id | uuid | not null |
+-------------+---------+-------------+
每当插入、更新或删除 votes
中的一行时,我想使用子查询更新相关课程的 votes_total
列。这是我尝试过的:
CREATE PROCEDURE update_lesson_votes_total()
LANGUAGE SQL
AS $$
UPDATE lessons
SET votes_total = (
SELECT SUM(CASE WHEN positive THEN 1 ELSE -1 END)
FROM votes
WHERE lesson_id = NEW.lesson_id
)
WHERE id = NEW.lesson_id;
$$;
CREATE TRIGGER votes_change
AFTER INSERT OR UPDATE OR DELETE ON votes
FOR EACH ROW
EXECUTE PROCEDURE update_lesson_votes_total();
但是,当我在迁移中尝试 运行 时,出现以下错误:
(Postgrex.Error) ERROR 42601 (syntax_error) cannot insert multiple commands into a prepared statement
您好,您的函数必须 return 一个触发器。您不能在删除触发器中使用 new。您必须创建至少 2 个调用相同函数的触发器,并使用 TG_OP
了解该函数是由插入、更新或删除触发的。
然后在 case 或 if 语句中,您可以使用 new 或 old 来获取 id 的值。
CREATE FUNCTION update_lesson_votes_total()
returns trigger
LANGUAGE plpgsql
AS $$
begin
UPDATE lessons
SET votes_total = (
SELECT SUM(CASE WHEN positive THEN 1 ELSE -1 END)
FROM votes
WHERE lesson_id = NEW.lesson_id
)
WHERE id = NEW.lesson_id;
return null;
end;
$$;
CREATE TRIGGER votes_change_u_i
AFTER INSERT OR UPDATE ON votes
FOR EACH ROW
EXECUTE PROCEDURE update_lesson_votes_total();
CREATE TRIGGER votes_change_d
AFTER DELETE ON votes
FOR EACH ROW
EXECUTE PROCEDURE update_lesson_votes_total();
在我的应用程序中,我有几个表,lessons
和 votes
。它们的外观如下:
课程
+-------------+---------+----------------------+
| Column | Type | Modifiers |
|-------------+---------+----------------------|
| id | uuid | not null |
| votes_total | integer | not null default 0 |
+-------------+---------+----------------------+
投票
+-------------+---------+-------------+
| Column | Type | Modifiers |
|-------------+---------+-------------|
| positive | boolean | not null |
| user_id | uuid | not null |
| lesson_id | uuid | not null |
+-------------+---------+-------------+
每当插入、更新或删除 votes
中的一行时,我想使用子查询更新相关课程的 votes_total
列。这是我尝试过的:
CREATE PROCEDURE update_lesson_votes_total()
LANGUAGE SQL
AS $$
UPDATE lessons
SET votes_total = (
SELECT SUM(CASE WHEN positive THEN 1 ELSE -1 END)
FROM votes
WHERE lesson_id = NEW.lesson_id
)
WHERE id = NEW.lesson_id;
$$;
CREATE TRIGGER votes_change
AFTER INSERT OR UPDATE OR DELETE ON votes
FOR EACH ROW
EXECUTE PROCEDURE update_lesson_votes_total();
但是,当我在迁移中尝试 运行 时,出现以下错误:
(Postgrex.Error) ERROR 42601 (syntax_error) cannot insert multiple commands into a prepared statement
您好,您的函数必须 return 一个触发器。您不能在删除触发器中使用 new。您必须创建至少 2 个调用相同函数的触发器,并使用 TG_OP
了解该函数是由插入、更新或删除触发的。
然后在 case 或 if 语句中,您可以使用 new 或 old 来获取 id 的值。
CREATE FUNCTION update_lesson_votes_total()
returns trigger
LANGUAGE plpgsql
AS $$
begin
UPDATE lessons
SET votes_total = (
SELECT SUM(CASE WHEN positive THEN 1 ELSE -1 END)
FROM votes
WHERE lesson_id = NEW.lesson_id
)
WHERE id = NEW.lesson_id;
return null;
end;
$$;
CREATE TRIGGER votes_change_u_i
AFTER INSERT OR UPDATE ON votes
FOR EACH ROW
EXECUTE PROCEDURE update_lesson_votes_total();
CREATE TRIGGER votes_change_d
AFTER DELETE ON votes
FOR EACH ROW
EXECUTE PROCEDURE update_lesson_votes_total();