触发器postgresql上的循环被卡住

触发器postgresql上的循环被卡住,sql,postgresql,Sql,Postgresql,我试图创建一个触发器来控制参数不为NULL,但当我尝试插入时,例如: INSERT INTO puntuacions(puntuacio, contingut, data) VALUES (6,NULL,CURRENT_DATE); 控制台在一个大循环上启动,试图在函数内部插入。我不确定我是必须在函数上插入还是在触发器末尾插入。 顺便说一句,在avg select上,我正在尝试将select中的avg值设置为insert on表格。 我有以下代码: 功能: create or replace

我试图创建一个触发器来控制参数不为NULL,但当我尝试插入时,例如:

INSERT INTO puntuacions(puntuacio, contingut, data) VALUES (6,NULL,CURRENT_DATE);
控制台在一个大循环上启动,试图在函数内部插入。我不确定我是必须在函数上插入还是在触发器末尾插入。 顺便说一句,在avg select上,我正在尝试将select中的avg值设置为insert on表格。 我有以下代码:

功能:

create or replace function p_controla() returns trigger as $controla_puntuacions$
begin
IF new.puntuacio IS NULL OR new.contingut IS NULL OR new.data IS NULL
THEN
RAISE 'SIUSPLAU OMPLE TOTES LES DADES DE LA TAULA';
ELSE
INSERT INTO puntuacions(puntuacio, contingut, data) VALUES (new.puntuacio,new.contingut,new.data);
UPDATE continguts SET puntuacio = (SELECT AVG(puntuacio) FROM puntuacions WHERE contingut = new.contingut) WHERE idcontingut = new.contingut;
RAISE ' OK! ';
END IF;
END;
$controla_puntuacions$ language plpgsql;
触发:

create trigger controla_puntuacions
before insert on puntuacions
for each row execute procedure p_controla();

此触发器有四个问题:

  • 您希望
    INSERT INTO puntuacions
    插入一条由触发器处理的记录。触发器不是这样工作的<触发器函数中的code>INSERT INTO puntuacions指示数据库插入另一行。它还将再次触发此触发器,并将导致无限递归。插入的行位于新的
    中。触发器返回
    new
    后,
    new
    中的值将插入到此表中
  • 基于puntuacions中的数据更新continguts
    在插入前触发器中不合适,因为该行尚未插入
  • 升起“OK!”引发异常。因此,即使所有值都不是null,插入也不会正确完成
  • 触发器缺少
    返回
    。修复3时,这将导致运行时错误
  • 一个问题是每行执行过程的语法
    。这种语法仍然有效,但它已经过时,现在已经被弃用了。此处应使用关键字
    函数
    ,而不是
    过程

    为了更新continguts,您可以创建一个after-insert触发器。 如果要在触发器完成后插入行,它必须返回
    new
    。 如果您只想显示一条消息“OK”,可以使用
    raisenotice

    潜在解决方案:

    插入前触发器的函数:

    create or replace function p_controla() returns trigger as $controla_puntuacions$
    begin
    IF new.puntuacio IS NULL OR new.contingut IS NULL OR new.data IS NULL
    THEN
    RAISE 'SIUSPLAU OMPLE TOTES LES DADES DE LA TAULA';
    ELSE
    RAISE NOTICE ' OK! ';
    END IF;
    RETURN new;
    END;
    $controla_puntuacions$ language plpgsql;
    
    create trigger puntuacions_after_ins
    after insert on puntuacions
    for each row execute function puntuacions_after_ins();
    
    插入触发功能后:

    create or replace function puntuacions_after_ins() returns trigger as $puntuacions_after_ins$
    begin
    UPDATE continguts SET puntuacio = (SELECT AVG(puntuacio) FROM puntuacions WHERE contingut = new.contingut) WHERE idcontingut = new.contingut;
    RETURN new;
    END;
    $puntuacions_after_ins$ language plpgsql;
    
    插入触发器后:

    create or replace function p_controla() returns trigger as $controla_puntuacions$
    begin
    IF new.puntuacio IS NULL OR new.contingut IS NULL OR new.data IS NULL
    THEN
    RAISE 'SIUSPLAU OMPLE TOTES LES DADES DE LA TAULA';
    ELSE
    RAISE NOTICE ' OK! ';
    END IF;
    RETURN new;
    END;
    $controla_puntuacions$ language plpgsql;
    
    create trigger puntuacions_after_ins
    after insert on puntuacions
    for each row execute function puntuacions_after_ins();
    

    after insert函数中的返回值被忽略,但无论如何,该函数必须返回一些内容。

    此触发器基本上实现了一个约束。为什么?为什么不将这些列定义为
    notnull