Python Postgres触发器找不到返回
这是我的扳机:Python Postgres触发器找不到返回,python,postgresql,triggers,sqlalchemy,flask-sqlalchemy,Python,Postgresql,Triggers,Sqlalchemy,Flask Sqlalchemy,这是我的扳机: CREATE OR REPLACE FUNCTION update_played () RETURNS trigger AS $BODY$ DECLARE v_count_played integer; BEGIN SELECT count(*) INTO STRICT v_count_played FROM history WHERE song_id = NEW.song_id; EXCEPTION WHEN NO_DATA_FOU
CREATE OR REPLACE FUNCTION update_played ()
RETURNS trigger
AS
$BODY$
DECLARE
v_count_played integer;
BEGIN
SELECT count(*) INTO STRICT v_count_played FROM history WHERE song_id = NEW.song_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE EXCEPTION 'history count for song % not found', NEW.song_id;
WHEN TOO_MANY_ROWS THEN
RAISE EXCEPTION 'history count did not aggregate';
EXECUTE 'UPDATE song SET count_played = $1 WHERE id = $2'
USING v_count_played, NEW.song_id;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
create trigger update_played_trigger
after insert on history
for each row
execute procedure update_played();
它给出了错误:
sqlalchemy.exc.InternalError:(psycopg2.InternalError)控制到达触发器过程的末尾,但未返回
您误解了
异常
关键字。如果我改变你的缩进来匹配它的工作原理,可能会帮助你理解<代码>异常与开始
和结束
一起作为块的一部分出现,就像其他语言中的try{}catch{}
一样。所以它是这样工作的:
BEGIN
SELECT count(*) INTO STRICT v_count_played
FROM history WHERE song_id = NEW.song_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE EXCEPTION 'history count for song % not found', NEW.song_id;
WHEN TOO_MANY_ROWS THEN
RAISE EXCEPTION 'history count did not aggregate';
EXECUTE 'UPDATE song SET count_played = $1 WHERE id = $2'
USING v_count_played, NEW.song_id;
RETURN NULL;
END;
这里发生的事情是运行选择
。如果发现无数据
异常,则引发
。如果引发的异常行太多,则在同一块中,引发异常
后存在无法访问的代码,该异常执行并返回
如果选择中没有异常,则不会采取进一步的操作,该过程只会退出,不返回任何内容
我认为你打算写的是:
BEGIN
BEGIN
SELECT count(*) INTO STRICT v_count_played FROM history WHERE song_id = NEW.song_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE EXCEPTION 'history count for song % not found', NEW.song_id;
WHEN TOO_MANY_ROWS THEN
RAISE EXCEPTION 'history count did not aggregate';
END;
EXECUTE 'UPDATE song SET count_played = $1 WHERE id = $2'
USING v_count_played, NEW.song_id;
RETURN NULL;
END;
谢谢你明确的回答。我注意到它在历史记录
中的所有行中都运行(现在已修复),尽管它在后续插入中没有运行。触发器就是这样工作的吗?如果我添加一个新触发器,它将在第一次运行时对每一个现有行执行该操作,即使只插入一个新行?@Tjorriemorrie-Er。否。触发器对现有行不执行任何操作,只对新行触发。我怀疑你的触发逻辑不对。如果你不明白,请发布一个新的问题,并链接回这个问题,以了解上下文。