默认情况下Postgres TRIGGER
的事务是否像(我读过的)在MySQL中?
我创建了TRIGGER
procedure,使用简单的IF
来限制列的值,使用其他TABLE
的值,如果违反了限制,则使用后续UPDATE
我希望将其放在一个TRANSACTION
中,但如果我将IF
... THEN UPDATE
与BEGIN
包裹在一起...... {{1} },它给出了错误
COMMIT
默认情况下SQL error:
ERROR: syntax error at or near ";"
LINE 2: BEGIN;
^
是TRIGGER
al?如果没有,TRANSACTION
如何TRIGGER
al?
码
这是TRANSACTION
的{{1}}:
ON INSERT OR UPDATE
我很想做一个articles
或BEGIN
BEGIN; /* this first TRANSACTION line causes error */
IF (NEW.votes_used > (SELECT votes_available FROM vote_totals
WHERE vote_totals.user_id = NEW.user_id)) THEN
UPDATE articles SET votes_used = (SELECT votes_available FROM vote_totals
WHERE vote_totals.userID = NEW.user_id) WHERE user_id = NEW.user_id;
END IF;
COMMIT; /*last TRANSACTION line */
RETURN NULL;
END;
在数据进入之前将其扼杀在萌芽状态,但我不知道如何使用{{1}我已经读过CHECK
s不能使用子查询。我想我读到这是要走的路,但我必须透露我是db noob。
答案 0 :(得分:1)
触发器内部不需要UPDATE
。您可以将值指定给NEW.votes_used
使用类似:
BEGIN
IF (NEW.votes_used > (SELECT votes_available FROM vote_totals
WHERE vote_totals.user_id = NEW.user_id)) THEN
NEW.votes_used := (SELECT votes_available FROM vote_totals
WHERE vote_totals.userID = NEW.user_id);
END IF;
RETURN NEW;
END;
或者
BEGIN
NEW.votes_used := LEAST(NEW.votes_used, (SELECT votes_available
FROM vote_totals
WHERE vote_totals.userID = NEW.user_id));
RETURN NEW;
END;
这必须是BEFORE UPDATE
触发器才能工作。 (因为所有BEFORE UPDATE
触发器都必须RETURN NEW
)。
如果你想用触发器模拟检查约束 - 尝试类似:
BEGIN
IF (NEW.votes_used > (SELECT votes_available
FROM vote_totals
WHERE vote_totals.user_id = NEW.user_id))
THEN RAISE EXCEPTION 'Not enough votes';
END IF;
RETURN NEW;
END;
答案 1 :(得分:0)
触发器是事务性的,因为它们的操作可以回滚。你没有必要做任何让它们像那样工作的东西。
语法错误就是这样。没有看到代码就很难告诉你更多。