Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » PostgreSQL »

como hacer este trigger????

Estas en el tema de como hacer este trigger???? en el foro de PostgreSQL en Foros del Web. Hola amigos, tengo una duda q no he podido resolver, lo q pasa q en mi bd tengo las tablas familia, padre, madre, niño y ...

  #1 (permalink)  
Antiguo 23/05/2009, 16:44
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
como hacer este trigger????

Hola amigos, tengo una duda q no he podido resolver, lo q pasa q en mi bd tengo las tablas familia, padre, madre, niño y familia_x_hijos, y lo q necesito hacer es un trigger q al momento de eliminar un niño y si este niño tiene mas hermanos q solo me elimine a este niño de la tabla familia_x_hijos, ya q el trigger q tengo hasta ahora me elimina a toda la familia al eliminar a un niño los trigger q tengo para esto son:
Código:
Create or replace function eliminar_familia_x_hijos() returns trigger as

'
declare
Begin




delete from familia_x_hijos where old.id_familia=id_familia;



return old;
End;
'

language 'plpgsql';

create trigger borrar_familia_x_hijos_antes_de_familia before
delete on familia
for each row execute procedure eliminar_familia_x_hijos();
este me elimina al niño q pertenece a esa familia este otro me elimina a la familia del niño despues de eliminar al niño en la tabla faimiklia_x_hijos :
Código:
Create or replace function eliminar_nino() returns trigger as

'
declare
Begin

delete from familia where old.id_familia=id_familia;
return old;
End;
'

language 'plpgsql';

create trigger borrar_antes_de_nino before
delete on nino
for each row execute procedure eliminar_nino();
y me pregunta es como puedo hacer el trigger q solo me elimine al niño q kiero eliminar de la tabla familia_x_hijos, ya q con los trigger q tengo me eliminara todo
como puedo hacer en el trigger el select para q solo me elimine al niño q kiero eliminar de la tabla familia_x_hijos sin q me elimine a la familia completa en el caso de q este niño tenga mas hermanos???.... ruego su ayuda amigos.... de antemano gracias.... bye
  #2 (permalink)  
Antiguo 24/05/2009, 07:59
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

En la estructura del trigger puedes usar sentencias if para validar si una familia sigue teniendo hijos después de borrar el hijo actual.

Si es así, que se ejecute la sentencia delete from familia. De lo contrario, que solo se borre el niño.

Un saludo.
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #3 (permalink)  
Antiguo 24/05/2009, 14:27
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

Hola huesos, gracias por responder mitema, si si te entiendo la logica, pero en lo q kedo trunco es en el codigo como lo puedo hacer??? como se hace un select dentro de un trigger??? se hace de forma normal??, he buscado un tipo de ejemplo asi, pero no he enkontrado nada parecido, es eso en cuanto a codigo quedo trunco, porque no se como iria la estructura del trigger con un select....porfavor si tienes algun ejemplillo o algo similar, para q me sirva de guia porfa.... de antemano gracias.... bye
  #4 (permalink)  
Antiguo 25/05/2009, 09:48
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

r0xdrig0

hay un tipo de variable en pl/pgsql llamada record, que puede recoger el valor de las variables de una consulta para usarlas despues.

Como se usa?
Te mostraré un pequeño ejemplo de como hago uso del valor de cierto campo en la base de datos.

Código sql:
Ver original
  1. CREATE OR REPLACE FUNCTION datosbs(codigo CHARACTER VARYING, fechabs DATE)
  2.   RETURNS DOUBLE PRECISION AS
  3. $BODY$
  4. DECLARE
  5. regBS record;
  6. BS DOUBLE PRECISION;
  7. BEGIN
  8. SELECT INTO regBS qtotal FROM bsol WHERE iestacion = codigo AND fecbsol = fechaBS;
  9. BS := regBS.qtotal;
  10. RETURN BS;
  11. END;
  12. $BODY$
  13.   LANGUAGE 'plpgsql' VOLATILE;
  14. ALTER FUNCTION datosbs(codigo CHARACTER VARYING, fechabs DATE) OWNER TO postgres;

En regBS se almacena el valor de qtotal que es un campo de la tabla bsol.
Es muy importante la clausula INTO.
Despues la retorno como variable.

Espero te sirva.

Cuentanos como te va.
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #5 (permalink)  
Antiguo 25/05/2009, 13:58
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

Hola huesos, gracias por tu ayuda, pero aun no logro comprender mucho, ya q solo he trabajado con triggerss simples, mi duda esta en como hago para comprobar si en la familia del niño existen mas hermanos, como hago la consulta dentro de la funcion q me mostraste??? esa funcion la hago dentro del trigger q tengo para eliminar familia o lla hago a parte?? y si la hago a parte como la llamo??? y lo otro y lo ultimo como hago para obtener el codigo de la familia del niño??? ya q solo traigo el id del niño como campo old de ningun lado traigo como campo old el id de la familia del niño , espero se entienda mi duda y me puedas/puedan guira... de antemano gracoas..... bye
  #6 (permalink)  
Antiguo 25/05/2009, 14:16
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

r0xdrig0

La sintaxís que te digo es así. Acomodalo bien para tu caso.

Código sql:
Ver original
  1. CREATE OR REPLACE FUNCTION eliminar_nino() RETURNS TRIGGER AS
  2. $$
  3. DECLARE
  4. nino record;
  5. BEGIN
  6. SELECT INTO nino COUNT(id_familia) AS numhijos FROM familia WHERE id_nino=NEW.id_nino;
  7. IF nino.numhijos = 0 THEN  
  8.   DELETE FROM familia WHERE OLD.id_familia=id_familia;
  9. END IF;
  10. RETURN OLD;
  11. END;
  12. $$
  13. LANGUAGE 'plpgsql';
  14.  
  15. CREATE TRIGGER borrar_antes_de_nino BEFORE
  16. DELETE ON nino
  17. FOR each ROW EXECUTE PROCEDURE eliminar_nino();

Numhijos es el alias que le damos al conteo y que se puede acceder mediante el record. Por eso se llama nino.numhijos para hacer la comparación.

Según entiendo, deseas borrar la familia solo si ya no tiene mas hijos registrados.

Porque borrarias la familia antes de borrar en la tabla niño?
Ten cuidado con el momento en que se ejecutan los eventos.

Este pequeño manual me ha servido mucho.
http://www.scribd.com/doc/102837/Triggers-en-PostgreSQL

Nos cuentas como te va.
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #7 (permalink)  
Antiguo 25/05/2009, 14:36
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

Ok, huesos, gracias nuevamente, probare y cualquier cosa posteo en este mismo tema (sorry mi intension no es molestar ni nada por el estilo) gracias nuevamente, probare y cualquier cosa posteo..... bye.
  #8 (permalink)  
Antiguo 25/05/2009, 15:53
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

No molestas r0xdrig0
Ese es el objetivo del foro. Ayudarnos los unos a los otros.
Un saludo.
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #9 (permalink)  
Antiguo 25/05/2009, 23:11
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

Hola huesos, gracias me resulto, pero ahora tengo un problema con otro trigger q es el de visita/visitante lo q pasa es q tengo una relacion fuerte entre el niño y el visitante donde se me genera la tabla visita, la tabla visitante tiene los campos:

|TABLA VISITANTE|

|id_visitante| |nombre_visitante| |apellido_visitante| |etc...|

y la tabla visita tiene los siguientes campos:
|TABLA VISITA|

|id_visitante| |id_nino| |etc...|

y tengo los siguientes triggers q supuestamente me elimina al visitante y la visita antes de eliminar al niño estos son:
trigger para eliminar visitante antes de visita:
Código:
Create or replace function eliminar_visitante() returns trigger as

'
declare
Begin






delete from visitante where old.id_visitante=id_visitante;
return old;
End;
'

language 'plpgsql';

create trigger borrar_antes_de_visita before
delete on visita
for each row execute procedure eliminar_visitante();
y el ara eliminar visita lo tengo con el trigger en donde elimino todos los otros datos del niño, pero lo q pasa q las otras tablas solo tienen el id de la misma y el id del niño ejemmplo; la tabla educacion tiene id_educacion e id_nino, y la tabla visitante tiene solo id visitante es por eso q cuando ejecuto el trigger no me elimina pq no encuentra el id_visitante eni el de visita, el trigger en cuestion es este:
Código:
Create or replace function eliminar_nino() returns trigger as

'
declare
Begin
delete from actividad where old.id_nino=id_nino;

delete from beneficio where old.id_nino=id_nino;

delete from educacion where old.id_nino=id_nino;

delete from nino_vive_en where old.id_nino=id_nino;

delete from salud where old.id_nino=id_nino;

delete from trabajo where old.id_nino=id_nino;

delete from visita where old.id_nino=id_nino;


return old;
End;
'

language 'plpgsql';

create trigger borrar_antes_de_nino before
delete on nino
for each row execute procedure eliminar_nino();
ese es el trigger pero no me elimina pq me dice q id_visita aun sigue presente en la tabla visitante, y no se en q esta fallando.... porfavor amigos ruego me guien esto de los triggers me tienen desesperado!!! porfavor ayuda!!!!!! de antemano gracias... bye
  #10 (permalink)  
Antiguo 26/05/2009, 07:54
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

r0xdrig0

Por lo que veo, quieres que cuando se elimine un niño, se borren todas las dependencias de las otras tablas.

Haz pensado en que los constraints de la tabla permitan un delete on cascade? De esta forma, con solo borrar el niño de la tabla, se borran todas las dependencias.
Así te evitas dolores de cabeza. Además, aunque los triggers son una herramienta fantástica, su uso debe ser moderado, puede traer muchas complicaciones en el mantenimiento de una BD.

Volviendo al tema..
No sería mejor en un solo trigger (El ultimo)... recuperar antes de borrar el nino de visita, el id_visitante?

Con ese id_visitante poder borrarlo en el mismo trigger de la tabla visitante?

Se puede dar el caso de que un visitante visite varios niños y no sea correcto borrar el visitante, por el solo hecho de borrar un niño?


Nos cuentas como te va.
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #11 (permalink)  
Antiguo 27/05/2009, 15:26
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

Hola huesos, probe lo de delete en cascada pero no me convence, prefiero hacerlo como me dices tu recuperando el id_visitante antes de borrar al niño de dicha tabla, pero mi problema es con el codigo :S, ¿como lo hago en codigo para recuperar el id del visitante para asi poder eliminar al niño sin eliminar al visitante en el caso q este tenga visitas a otros niños??? seria similar a la funcion q tengo para eliminar a un niño de una familia sin eliminar a esta??? como dije, he intentado en cuanto a codigo pero no me a resultado porfavor si es posible algun ejemplo se los agradeceria en el alma ya q este problema me tiene truncadicimo..... de antemano gracias.... bye
  #12 (permalink)  
Antiguo 27/05/2009, 19:07
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

r0xdrig0

El procedimiento es totalmente igual al planteado anteriormente.
Lo unico que cambia, es que puedes hacer un conteo del id_visitante en la tabla quw tenga que ver con el niño. Si es mayor a 1, quiere decir que existen mas niños a los cuales ha visitado y no se borra. Si es uno o cero que lo borre. La sintaxis es la misma, no debes hacer uso de nuevo código. Intenta hacerlo, y si tienes problemas vuleve a postear.

Un saludo
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #13 (permalink)  
Antiguo 29/05/2009, 13:32
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

Hola denuevo amigos, aun sigo aproblemado con el trigger de visita, me manda el siguiente error al eliminar a un niño; el error es:

---------------------------------------------------------------------------------------------
ERROR: record "new" is not assigned yet
DETAIL: the tuple structure of a not-yet-assigned record is indeterminate
CONTEXT: PL/pgSQL function "eliminar_visitante" line 8 at SQL statement
---------------------------------------------------------------------------------------------
no se pq me manda este error he provado con new y con old pero me sigue mandando el mismo error, el trigger en cuestion es el siguiente:

Código:
CREATE OR REPLACE FUNCTION eliminar_visitante() returns TRIGGER AS
  
      $$
  
      declare
   
      nino record;
  
      Begin
  
      SELECT INTO nino count(rut_visitante) AS numvisitas FROM visita WHERE rut_visitante=old.rut_visitante;
   
      IF nino.numvisitas = 0 then  
  
        DELETE FROM visitante WHERE old.rut_visitante=rut_visitante;
  
      end IF;
 
      RETURN old;
  
      End;
 
      $$
 
      LANGUAGE 'plpgsql';
 
       
  
      CREATE TRIGGER borrar_visitante before
  
      DELETE ON nino
 
      FOR each row execute procedure eliminar_visitante();
en q estoy fallando amigos???.... porfavor ayuda!!!!!!! esto me tiene urgidicimo!!!! pls ayuda!! de antemano gracias.... bye
  #14 (permalink)  
Antiguo 29/05/2009, 15:18
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

r0xdrig0 seguro en ninguna parte del trigger utilizas un valor new?

En que linea te marca este error?

un saludo
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #15 (permalink)  
Antiguo 29/05/2009, 16:07
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

Hola huesos, el error me lo da en la linea 8 q es esta:
Código:
DELETE FROM visitante WHERE old.rut_visitante=rut_visitante;
es q lo cambie por new la parte del WHERE old.rut_visitante= old.rut_visitante la cambie por WHERE old.rut_visitante= .rut_visitante, hice a este cambio debido a q con old igaul me lanza el mismo error en la misma linea por eso probe con ambos pero pero con ambos me manda el mismo error

en q estoy fallando??

porfavor ya no se en q estoy fallando y como les digo probe con ambos con new y old pero con ambos me manda el mismo error, obviamente q recalcandome el NEW o el OLD segun lo haya probado el error es este:
Código:
CREATE OR REPLACE FUNCTION eliminar_visitante() returns TRIGGER AS
  
      $$
  
      declare
   
      nino record;
  
      Begin
  
      SELECT INTO nino count(rut_visitante) AS numvisitas FROM visita WHERE rut_visitante=new.rut_visitante;
   
      IF nino.numvisitas = 0 then  

	delete from visita where old.id_nino=id_nino;
  
        DELETE FROM visitante WHERE old.rut_visitante=rut_visitante;// esta es la linea donde me manda el error
  
      end IF;
 
      RETURN old;
  
      End;
 
      $$
 
      LANGUAGE 'plpgsql';
 
       
  
      CREATE TRIGGER borrar_visitante before
  
      DELETE ON nino
 
      FOR each row execute procedure eliminar_visitante();
aqui le escribo denuevo el error:

ERROR: record "NEW/OLD" is not assigned yet
DETAIL: The tuple structure of a not yet assigned record is indeterminate
CONTEXT: PL/pgSQL function "eliminar_visitante" line 8 at SQL statement

ese es el error q me tira, el error del record lo puse con NEW/OLD pq aun q pruebe con cada uno de ellos me manda el mismo error.... porfavor amigos en q estoy fallando??? ruego su ayuda!!!!! de antemano gracias.... bye...
  #16 (permalink)  
Antiguo 30/05/2009, 10:04
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

Sospecho algo r0xdrig0 basado en un post anterior.

Nos contabas que entre visitante y niños habia una tabla intermedia producto de una relaciòn n:m(visitas).

old.rut-visitante donde lo ingresas al evento?

Creo que primero vdebes obtener el rut-visitante antes de borrar el niño de la tabla visita. Por que el sistema desconoce que es el rut-visitante.

En pocas palabras, creo que la solución a tu problema es almacenar el rut-visitante producto de la consulta
Código sql:
Ver original
  1. SELECT INTO variable rut-visitante FROM visitas WHERE id-nino=OLD.id_nino;
posteriormente, borrar el niño de visitas y borrar visitante con
Código sql:
Ver original
  1. DELETE FROM visitante WHERE rut_visitante=variable;

Pruebalo y nos cuentas.
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #17 (permalink)  
Antiguo 09/06/2009, 14:15
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

Hola amigos, yo aqui aun, no habia posteado antes pq tuve q hacer un viaje por razones de fuierza mayor, aun estoy con el problema del trigger para eliminar al visitante y las visitas hechas al niño antes de eliminar a este; tengo el siguiente trigger y me manda el siguiente error. el trigger es:
Código:
CREATE OR REPLACE FUNCTION eliminar_visitante() returns TRIGGER AS
  
      $$
  
      declare
   
      visitante_rut record;
  
      Begin
  
      SELECT INTO visitante_rut rut_visitante FROM visita WHERE id_nino=old.id_nino;
   
      DELETE FROM visita where id_nino=old.id_nino; 
  
        DELETE FROM visitante WHERE rut_visitante=visitante_rut;
  
      
 
      RETURN old;
  
      End;
 
      $$
 
      LANGUAGE 'plpgsql';
 
       
  
      CREATE TRIGGER borrar_visitante before
  
      DELETE ON nino
 
      FOR each row execute procedure eliminar_visitante();
ese es el trigger en cuestion y me esta mandando el siguiente error:

ERROR: operator does not exist: character varying= record
LINE 1: DELETE FROM visitante WHERE rut_visitante= $1
HINT: no operator matches given name and argument type(s). You may need to add explicit type casts.
QUERY: DELETE FROM visitante WHERE rut_visitante =$1
CONTEXT: PG/pgSQL function "eliminar_visitante" line 12 at SQL statement.

Ese es el error q me manda al ejecutar el trigger y no se pq, si estoy declarando la variable record donde corresponde, pero al parecer no me la reconoce como declarada.... en q estoy fallandoo ahora amigos??? porfavor ruego su ayuda!!!!! me tiene urgidicimo este problema ya q llevo tiempo tratando de resolverlo pero no he podido porefavor amigos guienme plssssssss y disculpen la demora del posteo, pero tuve q hacer un viaje de urgencia y acabo de llegar de antemano gracias... espero me puedan ayudar .... bye bye
  #18 (permalink)  
Antiguo 09/06/2009, 14:42
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

Cita:
DELETE FROM visitante WHERE rut_visitante=visitante_rut;
Cuando haces esto, llamas al record completo y no estas haciendo ningún tipo de casteo a esta variable. Para acceder al valor que se encuentra en el record, debe ser así:

Código sql:
Ver original
  1. DELETE FROM visitante WHERE rut_visitante=visitante_rut.rut_visitante;

Prueba eso y nos cuentas. Todos los errores están enfocados en esa linea.

Un saludo.
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #19 (permalink)  
Antiguo 11/06/2009, 10:55
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

Hola amigos, gracias por su ayuda solucione el problema con el trigger de visitas, pero ahora tengo un problema para eliminar a la familia, ya q no me la elimina y necesito q me elimine la familia y la familia_x_hijos y a su vez si la familia ya no tiene mas hijos q me elimine la informaciuon del padre y de la madre de su respectiva tabla (tablas padre y madre), el trigger q tengo por ahora es el siguiente:
Código:
CREATE OR REPLACE FUNCTION eliminar_familia() returns TRIGGER AS
  
      $$
  
      declare
   
      nino record;
  
      Begin
  
      SELECT INTO nino count(id_familia) AS numhijos FROM familia_x_hijos WHERE id_nino=old.id_nino;
   
      IF nino.numhijos = 0 then  
  
        DELETE FROM familia WHERE old.id_familia=id_familia;
  
      end IF;
 
      RETURN old;
  
      End;
 
      $$
 
      LANGUAGE 'plpgsql';
 
       
  
      CREATE TRIGGER borrar_familia_antes_de_menor before
  
      DELETE ON nino
 
      FOR each row execute procedure eliminar_familia();
ese es mi trigger q me cuenta kuantos hijos tiene la familia y si la familia tiene 0 hijos deberia eliminarme la familia completa, pero lo q necesecito y lo q no he podido hacer es q me elimine a la familia y a la vez q me elimine la informacion del padre y de la madre de sus respectivas tablas una vez q en la familia ya no existan mas hijos, en la tabla madre y padre suis respectivas pk son rut_padre y rut_madre la tabla familia tiene como pk id_familia, rut_madre y rut_padre y la tabla familia_x_hijos tiene como primary key compuestas id_familia e id_niño, esa es la estructura principal de las tablas involucradas, porfavor amigos guienme como puedo lograr este trigger!!!! de antemano gracias.... bye
  #20 (permalink)  
Antiguo 18/06/2009, 15:55
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

gos porfavor ayuda urgente!!!! aun no soluciono este problema porfavor ruego de su ayuda!!!!!!!!!.... de antemano gracias.... bye
  #21 (permalink)  
Antiguo 18/06/2009, 16:08
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

rodrigo

que problema tienes?

Como se comporta el trigger?

Que acciones está ejecutando?

Que estructura tiene la tabla niño?
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #22 (permalink)  
Antiguo 18/06/2009, 17:45
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

hola huesos, la estructura de mi tabla niño es
|id_nino (pk)| |nombre_nino| apellido_nino| etc...|

lo q necesito es q se me elimine a los padres una vez q se elimine al niño y ya la familia no tenga mas hijos pq hasta ahora solo me elimina las demas tablas pero no me elimina los datos de la tabla familia ni de las tablas padre y madre cuando la familia ya no tiene mas hijos y por lo tanto deja de existir.... las estructura de mis tablas es:
tabla familia:
|id_familia(pk) |rut_madre (fk)| rut_padre (fk)|

tabla padre:
|rut_padre|nombre_padre|etc...|

tabla madre:

|rut_madre (pk)| nombre_madre| etc...|

tabla familia_x_hijos

|id_familia (pk) (fk tabla familia)| id_nino (pk) (fk tabla nino)|

lo q no he podido lograr es q se elimine a la familia en la tabla familia y al padre y a la madre en sus respectivas tablas una vez q se elimina al niño y la familia ya no tiene mas hijos, logro eliminar todo en las demas tablas pero menos en esas q nombre, (ojala me entiendan) los triggers q qtengo para esto son:
TRIGGER ELIMINAR ANTES DE NIÑO:
Código:
Create or replace function eliminar_antes_de_nino() returns trigger as

'
declare
Begin
delete from actividad where old.id_nino=id_nino;

delete from beneficio where old.id_nino=id_nino;

delete from educacion where old.id_nino=id_nino;

delete from nino_vive_en where old.id_nino=id_nino;

delete from salud where old.id_nino=id_nino;

delete from trabajo where old.id_nino=id_nino;

delete from familia_x_hijos where old.id_nino=id_nino;


return old;
End;
'

language 'plpgsql';

create trigger borrar_todo_antes_de_nino before
delete on nino
for each row execute procedure eliminar_antes_de_nino();
este trigger me elimina los datos de todas las tablas antes de borrar al niño, pero no me borra familia_x_hijos

TRIGGER BORRAR FAMILIA ANTES DE NIÑO:
Código:
CREATE OR REPLACE FUNCTION eliminar_familia() returns TRIGGER AS
  
      $$
  
      declare
   
      nino record;
  
      Begin
  
      SELECT INTO nino count(id_familia) AS numhijos FROM familia_x_hijos WHERE id_nino=old.id_nino;
   
      IF nino.numhijos = 0 then  
  
        DELETE FROM familia WHERE old.id_familia=id_familia;
  
      end IF;
 
      RETURN old;
  
      End;
 
      $$
 
      LANGUAGE 'plpgsql';
 
       
  
      CREATE TRIGGER borrar_familia_antes_d_menor before
  
      DELETE ON nino
este trigger me elimina a la familia una vez q la familia ya no tiene mas hijos, pero no me funciona, y mi pregunta es como lo tengo q hacer para q una vez q me borre a la familia en caso q no tenga mas hijos, como borro al padre y a la madre de sus respectivas tablas, ya q como dije anteriormente logro borrar todos los datos de las demas tablas excepto los datos de las tablas padre, madre, familia_x_hijos y la tabla familia. como lo debo hacer en cuanto a codigo q debo agregar y como??? porfavor amigos llevo mucho tiempo tratando de hacerlo pero no lo logro RUEGO SU AYUDA AMIGOS!!!!.... de antemano gracias ... bye
  #23 (permalink)  
Antiguo 18/06/2009, 21:43
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

rodrigo

Los valores old y new se refieren a aquellos campos que están relacionados en la tabla sobre la cual opera el trigger.

En este caso, el trigger se dispara cuando se borra en la tabla niño y por lo que veo, esta tabla no tiene un campo id_familia.

Creo que eso es lo que te dice el error.

Debes hayar la familia del niño, guardarla en un record y hacer uso de ella con la misma sentencia.

Un saludo
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #24 (permalink)  
Antiguo 22/06/2009, 13:43
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

hola huesos he intentado hacerlo ero no lo logro, al obtener en un record el id de la familia como lo hago para q se me eliminen el padre y la madre de sus respectivas tablas ya q en las tablas padre y madre no tengo el campo id_familia??? como puedo hacer esto en cuanto a codigo porfavor amigos ayudaaa esto ya me supera y debo terminarlo luego porfavor!!!! como elimino al padre y a la madre de sus respectivas tablas una vez q se elimine la familia a la q estos pertenecen??? como hago esto en codigo??? porfavor amigos ruego su ayuda!!!! de antemano gracias.... bye.
  #25 (permalink)  
Antiguo 22/06/2009, 13:57
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

Rodrigo... no desesperes jeje

Ya tienes las herramientas para extraer la información de las tablas. Ya sabes que se hace con record o con otro tipo de variable pero asignada con la clusula into.
Eso lo haces bien.

Que veo en tu problema?
Tienes varias tablas y debes establecer la jerarquía de las mismas para saber de que tablas hay que borrar primero los datos. Por lo que veo en la estructura de tus tablas, debes primero extraer de la tabla familia_x_hijos el id_familia,rut_padre y rut_madre.
Luego preguntas el numerodeniños para esa familia (Eso ya lo haces aca IF nino.numhijos = 0 then) si el valor es cero, con el valor de rut_padre,rut_madre y id_familia puedes borrar los respectivos registros de las tablas.

Ahora si a la practica. Esto no lo he probado pero creo que te servirá.

Código sql:
Ver original
  1. CREATE OR REPLACE FUNCTION eliminar_familia() RETURNS TRIGGER AS
  2.  
  3.       $$
  4.  
  5.       DECLARE
  6.    
  7.       nino record;
  8.  
  9.       BEGIN
  10.  
  11.       SELECT INTO nino id_familia,rut_padre,rut_madre,COUNT(id_familia) AS numhijos FROM familia_x_hijos WHERE id_nino=OLD.id_nino;
  12.    
  13.       IF nino.numhijos = 0 THEN  
  14.  
  15.         DELETE FROM familia WHERE id_familia=nino.id_familia;
  16.         DELETE FROM padre WHERE rut_padre=nino.rut_padre;
  17.         DELETE FROM madre WHERE rut_madre=nino.rut_madre;
  18.  
  19.  
  20.       END IF;
  21.  
  22.       RETURN OLD;
  23.  
  24.       END;
  25.  
  26.       $$
  27.  
  28.       LANGUAGE 'plpgsql';
  29.  
  30.        
  31.  
  32.       CREATE TRIGGER borrar_familia_antes_d_menor BEFORE
  33.  
  34.       DELETE ON nino

Segun entiendo la tabla familia cuenta con _padre

Fijate que la variable record, almacena todos los elementos de la consulta, por esto, es posible acceder con el record a lo que llamemos en la consulta.

Cuentanos como te va.
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #26 (permalink)  
Antiguo 22/06/2009, 14:00
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

ah ok el record abarca todos los campos de la tabla, era esa mi duda yo creia q para obtener cada campo tendria q hacer tantas consultas como necesitace, muchas gracias huesos, probare y te cuento .... bye
  #27 (permalink)  
Antiguo 22/06/2009, 18:21
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

hola huesos aca yo otra vez, probe el trigger q me diste para guiarme, pero al borrar la familia me da error, ya q en tabla familia_x_hijos esta compuesta asi:

|id_familia| id_nino|

asi esta compuesta la tabla familia_x_hijos, y la tabla familia esta compuesta asi:

|id_familia| rut_madre| rut_padre|

asi esta compuesta la tabla familia y en el trigger la consulta para borrar familia esta asi:
Código:
SELECT INTO nino id_familia,rut_padre,rut_madre,count(id_familia) AS numhijos FROM familia_x_hijos WHERE id_nino=old.id_nino;
  
  
            IF nino.numhijos = 0 then  
  
       
  
              DELETE FROM familia WHERE id_familia=nino.id_familia;
  
              DELETE FROM padre WHERE rut_padre=nino.rut_padre;
  
              DELETE FROM madre WHERE rut_madre=nino.rut_madre;
como ves, el select into va apuntando hacia la tabla familia_x_hijos, pero la tabla familia_x_hijos no posee los campos rut_madre ni rut_padre solo posee los campos id_familia y id_nino y el error q me manda es q no encuentra ningun campo con nombre rut_madre ni rut_padre ya q el select into apunta a la tabla familia_x_hijos y esta no posee esos dos campos, solo posee los campos id_familia y id_nino, mi consulta ahora es como puedo hacer un select into hacia las dos tablas (familia_x_hijos y familia) ya q aparte del id_familia necesito obtener el rut_madre y rut_padre para eliminar a estos una vez q no tengan mas hijos, puedo hacer una especie de join en un select into o de q forma puedo capturar el valor de rut_madre y rut_padre para asi poder eliminar a estos en caso q no tengan mas hijos??? ojala se me entienda porfavor amigos ayuda!!!! se los ruego!!! de antemano gracias.... bye
  #28 (permalink)  
Antiguo 22/06/2009, 18:37
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

rodrigo.

prueba esto:
Código sql:
Ver original
  1. SELECT INTO nino id_familia,COUNT(id_familia) AS numhijos FROM familia_x_hijos WHERE id_nino=OLD.id_nino;
  2.  
  3.  
  4.             IF nino.numhijos = 0 THEN  
  5.  
  6.                        
  7.               SELECT INTO padres rut_padre,rut_madre FROM familia WHERE id_familia=nino.id_familia;
  8.  
  9.               DELETE FROM familia WHERE id_familia=nino.id_familia;
  10.  
  11.               DELETE FROM padre WHERE rut_padre=padres.rut_padre;
  12.  
  13.               DELETE FROM madre WHERE rut_madre=padres.rut_madre;

Sin embargo, lo que interesa es que entiendas bien que estas tratando de hacer y por que se dan los errores. La sentencia que te pasé en un ppio, fue error mio, por mirar mal la estructura de tus tablas en un post anterior, lo importante es saber la jerarquia de las tablas y cual debe ser el orden de borrado que se debe llevar a cabo.

Fijate que me valgo del id_familia para obtener el padre y madre de ese niño. padres es una nueva variable tipo record que debes declarar. Revisa muy bien las relaciones que existen entre las tablas y establece un orden de borrado.

Recuerda que los valores new. y old. se dan unicamente, cuando son los campos que intervienen en la tabla, para este caso el id_nino. Los que no estén involucrados, deben ser hallados basados en consultas.

Cuentanos como te va.
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #29 (permalink)  
Antiguo 22/06/2009, 19:01
 
Fecha de Ingreso: diciembre-2007
Mensajes: 385
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: como hacer este trigger????

hola huesos lo probe como me dijiste el trigger me quedo asi:
Código:
CREATE OR REPLACE FUNCTION eliminar_familia() returns TRIGGER AS

            $$

            declare
            nino record;
            padres record;
            Begin

            SELECT INTO nino id_familia,count(id_familia) AS numhijos FROM familia_x_hijos WHERE id_nino=old.id_nino;
 
            IF nino.numhijos = 0 then  

  
           SELECT INTO padres rut_padre,rut_madre FROM familia WHERE id_familia=nino.id_familia;

 

              DELETE FROM familia WHERE id_familia=nino.id_familia;

 

              DELETE FROM padre WHERE rut_padre=padres.rut_padre;

 
              DELETE FROM madre WHERE rut_madre=padres.rut_madre;
  
            end IF;

            RETURN old;
  
            End;

            $$

            LANGUAGE 'plpgsql';

            CREATE TRIGGER borrar_familia_antes_d_menor before

            DELETE ON nino

   for each row execute procedure eliminar_familia();
pero ahora me da este error y no se pq:S el error es este:

ERROR: column "familia_x_hijos.id_familia" must appear in the GROUP BY clause or be used in an aggregate function line 16 at SQL statement

ese es el error q me da ahora y de verdad q no se pq me da ese error ahora, a q se debe??? en q estoy fallando ahora??? porfavor amigos ayuda!!!! se los ruego!!!! porfavor!!! en q estoy fallando??? ayuda please!!! de antemano gracias.... y sorry por todo lo q he molestado con esto pero de verdad me tiene desesperado!!! de antemano gracias.... bye

CONTEXT: SQL statement SELECT id_familia, count(id_familia) AS numhijos FROM familia_x_hijos WHERE id_nino=$1

"
PL/pgSQL function "eliminar_familia"
  #30 (permalink)  
Antiguo 22/06/2009, 19:18
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: como hacer este trigger????

Cita:
column "familia_x_hijos.id_familia" must appear in the GROUP BY clause or be used in an aggregate function line 16 at SQL statement
Se debe a que esta consulta tiene un count diferente para cada id_familia, por lo que es necesario establecer el agrupamiento de la consulta.
La pregunta aca es:
En la tabla familia_x_hijos puede existir varias familias por niño? Si es así tiene sentido el error, de lo contrario no debería dar problema.
Solución:
SELECT id_familia, count(id_familia) AS numhijos FROM familia_x_hijos WHERE id_nino=$1 group by id_familia

Sin embargo, no termino de entender, como puede ser posible que en la tabla familia_x_hijos pueda existir varias familias por cada niño.

Aclaranos esto.
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 21:34.