代码之家  ›  专栏  ›  技术社区  ›  ElíasMarNev

Postgresql,检查插入时触发错误

  •  1
  • ElíasMarNev  · 技术社区  · 7 年前

    My table "Historial"

    CREATE TRIGGER VerificarInsercion
    BEFORE INSERT ON public."Historial"
    FOR EACH ROW 
    EXECUTE PROCEDURE VerificarHistorial();
    

    (我尝试删除“FOR EACH ROW”,因为我只想运行一次,而不是每行)

    BEGIN
      IF (SELECT Count (*) FROM public."Historial" WHERE estado = 1 AND "IDU" = NEW."IDU") < 1 THEN 
          INSERT INTO public."Historial" (usuario, vehiculo, mercancia, "combustibleInicial", ruta, "horaSalida", estado, "IDU", fecha)
          VALUES (NEW.usuario, NEW.vehiculo, NEW.mercancia, NEW."combustibleInicial", NEW.ruta, NEW."horaSalida", NEW.estado, NEW."IDU", NEW.fecha);
      END IF;
      RETURN null;
    END;
    

    当我在“历史”中插入一些数据时:

    INSERT INTO public."Historial" (usuario, vehiculo, mercancia, "combustibleInicial", ruta, "horaSalida", estado, "IDU", fecha) VALUES ('David', '3424SDA', 200, 50, 'Cáceres-Sevilla', 'dom, 3 sep, 05:20 PM', 1, 50, '2017-09-03T15:21:07.442Z')
    

    ERROR:  stack depth limit exceeded
    HINT:  Increase the configuration parameter "max_stack_depth" (currently 2048kB), after ensuring the platform's stack depth limit is adequate.
    CONTEXT:  SQL statement "SELECT (SELECT Count (*) FROM public."Historial" WHERE estado = 1 AND "IDU" = NEW."IDU") < 1"
    PL/pgSQL function verificarhistorial() line 2 at IF
    SQL statement "INSERT INTO public."Historial" (usuario, vehiculo, mercancia, "combustibleInicial", ruta, "horaSalida", estado, "IDU", fecha)
          VALUES (NEW.usuario, NEW.vehiculo, NEW.mercancia, NEW."combustibleInicial", NEW.ruta, NEW."horaSalida", NEW.estado, NEW."IDU", NEW.fecha)"
    PL/pgSQL function verificarhistorial() line 3 at SQL statement
    

    我检查了其他类似的回答,没有结果。

    有没有想过制作一个函数来检查是否有任何行具有与插入数据相同的IDU?

    2 回复  |  直到 7 年前
        1
  •  2
  •   klin    7 年前

    每次向表中插入新行时,都会调用触发器函数。如果您试图在函数中插入一行,则会再次调用该函数,依此类推。这样你就能实现 堆栈溢出 .

    BEGIN
        IF EXISTS (SELECT 1 FROM "Historial" WHERE estado = 1 AND "IDU" = NEW."IDU") THEN 
            RETURN null;
        END IF;
        RETURN new;
    END; $$;
    

    事实上,如果创建部分唯一索引,则不需要触发器:

    create unique index on "Historial" ("IDU") where estado = 1
    
        2
  •  1
  •   AhmadReza Payan    5 年前

    您不应该在触发器中插入新行,这会导致无限递归。我认为可以通过创建一个 Unique Index

    set search_path = public;
    create unique index on "Historial" ("IDU") where estado = 1;
    

    Update Command 已在Stackoverflow中回答,请参阅以下链接:

    Update a table with a trigger after update