Es natural que si eliminas el padre se elimine todo en cascada, por ejemplo supón que tienes el asiento con id 1 y es referenciado desde una tupla con id 2 en la tabla linea_asiento, entonces al tener una relación recursiva sobre la misma tabla línea_asiento si la clave foránea de asiento no acepta nulos en la tabla linea_asiento, donde quiera que tengas una relación recursiva donde la llave foránea de linea_asiento sea la 2, tendrías también la llave foránea de asiento o sea la 1.
Lo otro, que sucedería si al eliminar un asiento, este es referenciado desde la tabla linea_asiento, en una tupla que es el nodo raíz en tu jerarquía de la tabla recursiva, o sea que pasaría con todas las tuplas dependientes de ella? Espero que te haya podido ayudar. Saludos. -----Mensaje original----- De: Rodrigo Ruiz [mailto:[email protected]] Enviado el: lunes, 26 de diciembre de 2011 04:21:PM Para: Lazaro Rubén García Martinez CC: Lista PostgreSQL Asunto: Re: [pgsql-es-ayuda] Trigger no actúa al eliminar en tabla padre On 26/12/11 17:33, Lazaro Rubén García Martinez wrote: > Cuando te refieres a Padre que tiene Hijos, te refieres a la herencia que > posee postgres, o a relaciones de tipo 1:M o 1:1?? > > Podrías enviar el trigger? > > Saludos. > > -----Mensaje original----- > De: [email protected] > [mailto:[email protected]] En nombre de Rodrigo Ruiz > Enviado el: lunes, 26 de diciembre de 2011 03:44:PM > Para: Lista PostgreSQL > Asunto: [pgsql-es-ayuda] Trigger no actúa al eliminar en tabla padre > > Estimados/as, > tengo una tabla Padre que tiene Hijos, en la tabla hijos existe un > trigger para before delete y si se elimina un elemento padre, se > eliminan todos sus hijos en cascada. > El punto es que cuando elimino un hijo directamente, el trigger funciona > perfecto, pero si elimino un padre, el trigger en los hijos de dicho > padre no se dispara. Cabe destacar que el trigger en hijos va a buscar > algnos datos del padre para realizar ciertas tareas, me imagino que el > padre aún "existe" hasta eliminar todos sus hijos en cascada. > Se me ocurre eliminar la referencia de eliminar en cascada y crear un > trigger al eliminar un padre para eliminar las lineas directamente con > delete, pero quisiera saber por qué el trigger no funciona al eliminar > los hijos en cascada. > > Saludos cordiales, felices fiestas. > > Me refiero a una relación de tipo 0:n. Las tablas se llaman mgp_asiento y mgp_linea_asiento, asiento puede 0 o muchas líneas. mgp_asiento (id, fecha,...,etc) mgp_linea_asiento (id, mgp_asiento_id, monto_debe, monto_haber, saldo, mgp_linea_asiento_id,...,etc) Existen líneas que son creadas a partir de otras, por ello la relación mgp_linea_asiento_id dentro de las líneas, y si se cumplen algunas condiciones, al eliminar dichas líneas debo devolver el monto al saldo de la línea original, y eso no está ocurriendo cuando elimino el asiento y se borran las líneas de forma automática en cascada, no así cuando elimino la línea directamente. Clave foránea en mgp_linea_asiento: ALTER TABLE contable.mgp_linea_asiento ADD CONSTRAINT cmci_16 FOREIGN KEY (mgp_asiento_id) REFERENCES contable.mgp_asiento(id) MATCH SIMPLE ON DELETE CASCADE; Trigger before delete en mgp_linea_asiento: CREATE OR REPLACE FUNCTION contable.fn_elimina_linea_asiento_before() RETURNS trigger AS $$ DECLARE asiento RECORD; linea_origen RECORD; BEGIN -- Datos asiento padre SELECT * INTO asiento FROM contable.mgp_asiento WHERE id = OLD.mgp_asiento_id; IF asiento.mgp_tipo_asiento_id = 2 AND OLD.monto_debe > 0 THEN -- Datos línea de origen SELECT * INTO linea_origen FROM contable.mgp_linea_asiento WHERE id = OLD.mgp_linea_asiento_id; IF FOUND THEN UPDATE contable.mgp_linea_asiento SET saldo = saldo + OLD.monto_debe WHERE id = linea_origen.id; END IF; [...] RETURN OLD; END; $$ LANGUAGE 'plpgsql' VOLATILE; Espero se entienda. Saludos.- - Enviado a la lista de correo pgsql-es-ayuda ([email protected]) Para cambiar tu suscripción: http://www.postgresql.org/mailpref/pgsql-es-ayuda
