Re: duda sobre trigger

From: Fernando Hevia <fhevia(at)gmail(dot)com>
To: "Ing(dot) Esneiker Enriquez Cabrera" <eenriquez(at)cav(dot)desoft(dot)cu>
Cc: POSTGRES <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: duda sobre trigger
Date: 2014-04-03 19:04:02
Message-ID: CAGYT1XSuvwBT=o1s=PqEUpnk0+PQy9+oX_-wJhRCfbt2ajoqfQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

2014-04-03 15:40 GMT-03:00 Ing. Esneiker Enriquez Cabrera <
eenriquez(at)cav(dot)desoft(dot)cu>:

> El código de la función es:
>
>
>
> ...
>
>
>
> Al ejecutar update carpeta_mensaje set eliminado = false el servidor me
> retorna:
>
>
>
> ERROR: límite de profundidad de stack alcanzado
>
> HINT: Incremente el parámetro de configuración «max_stack_depth»
> (actualmente 2048kB), después de asegurarse que el límite de profundidad de
> stack de la plataforma es adecuado.
>
> CONTEXT: sentencia SQL: «SELECT 1 FROM ONLY "public"."nmusuario" x WHERE
> "id" OPERATOR(pg_catalog.=) $1 FOR SHARE OF x»
>
> sentencia SQL: «update carpeta_mensaje set nodo_terminal = false where id
> in (select id_padre from carpeta_mensaje where eliminado is false and
> id_padre is not null)»
>
> PL/pgSQL function "actualizar_carpeta_mensaje" line 14 at sentencia SQL
>
> sentencia SQL: «update carpeta_mensaje set nodo_terminal = false where id
> in (select id_padre from carpeta_mensaje where eliminado is false and
> id_padre is not null)»
>
>
>
> y esto una cantidad de veces exagerada.
>
>
>
> Espero que me puedan ayudar con este tema que aparentemente debería ser
> una cuestión muy simple.
>

El error indica que tienes un problema de recursividad: haces un update
sobre carpeta_mensaje que dispara la función trigger
actualizar_carpeta_mensaje que hace un update sobre la tabla
carpeta_mensaje que dispara el trigger actualizar_carpeta_mensaje que hace
un update ... y así.

Necesitas en tu función una condición de salida para cortar la
recursividad.
Por ejemplo:

IF (TG_OP = 'INSERT') THEN

if(NEW.id_padre is not null AND NEW.id_padre != OLD.id_padre) then

update carpeta_mensaje set nodo_terminal = false where id =
NEW.id_padre;

update carpeta_mensaje set id_menu_padre = m.id_menu_padre from
carpeta_mensaje m where m.id = NEW.id_padre and carpeta_mensaje.id = NEW.id;

end if;

END IF;

Si id_padre no cambió entonces esto no se dispara y el trigger tiene una
oportunidad de salir sin hacer cambios sobre su misma tabla.

Esta misma lógica aplica a las otras condiciones que tienes en la función
que luego disparan cambios sobre la misma tabla.

Saludos,
Fernando.

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Gilberto Castillo 2014-04-03 19:07:41 Re: duda sobre trigger
Previous Message Fernando Hevia 2014-04-03 18:44:50 Re: duda sobre trigger