Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 22-05-2007
Avatar de sitrico
[sitrico] sitrico is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Caracas, Venezuela
Posts: 295
Poder: 21
sitrico Va por buen camino
Un trigger que dispara un procedimiento que dispara un trigger...

Más que una pregunta es una duda. (es mi primera vez ) a ver:

Quiero manejar 2 tablas donde la inserción en la primera (co_detalleconsultas) causa la inserción en la segunda (ad_serviciosasignados) por medio de un procedimiento almacenado que genera el idservasig que al final del procedimiento se guarda en la 1ra tabla con un update.

¿ Este enfoque es viable y recomendable o mejor busco otra solución ?

--- el código ---

En un trigger after insert en co_detalleconsultas lanzo:

Código SQL [-]
execute procedure ad_asignarserviciosprestados(new.idpaciente, New.idservicio);

que llama al procedimiento

Código SQL [-]
CREATE PROCEDURE AD_ASIGNARSERVICIOSPRESTADOS (
    aidpaciente integer,
    aidservicio integer)
as
declare variable sidservasig integer;
declare variable didservicio integer;
declare variable cidpaciente integer;
declare variable diddetcons integer;
declare variable scantidadsesiones integer;
declare variable ssecionesrealizadas integer;
declare variable lsesiones integer;
begin
  FOR
  Select  d.IDDETCONS, s.idservasig, d.IdServicio, d.IdPaciente, s.cantidadsesiones, s.secionesrealizadas, l.sesiones
  from co_detalleconsultas d
  left join ad_serviciosasignados S
  on d.idpaciente = s.idpaciente And d.idservicio = S.idservicio And
    (s.cantidadsesiones is null or s.cantidadsesiones > s.secionesrealizadas)
  join dg_listaservicios L On d.idservicio = l.idservicio
  Where d.IdPaciente = :aIdPaciente and d.IdServicio = :aidservicio
  -- variables para los resultados
  into :diddetcons, :sidservasig, :dIdServicio, :cIdPaciente, :scantidadsesiones, :ssecionesrealizadas, :lsesiones
     DO
     BEGIN
     if (sidservasig is null) then
        Begin
        -- aqui se determina el nuevo ID usando un generador
        sidservasig = GEN_ID(GEN_AD_SERVICIOSASIGNADOS_ID,1);
        Insert into ad_serviciosasignados
           (idservasig, idservicio, idpaciente, iddetcons, cantidadsesiones, secionesrealizadas, fchinicio, fchfinal) values
           (:sidservasig, :dIdServicio, :cIdPaciente, :diddetcons, :lsesiones, 1, current_date, current_date);
        End
     Else
        Begin
        Update ad_serviciosasignados Set
            secionesrealizadas = :ssecionesrealizadas +1,
            fchfinal = current_date
        Where idservasig = :sidservasig;
        End
     Update co_detalleconsultas SET
        IDSERVASIG = :sidservasig
     Where co_detalleconsultas.iddetcons = :diddetcons;
     suspend;
     End
end

Que según (YO) cada vez que hay una consulta (de estetica) asigna la consulta (para efectos la pone en cuentas por cobrar - ad_serviciosasignados) y si se trata de un paquete (varias consultas = 1 asignación) aumenta el contador:

secionesrealizadas = :ssecionesrealizadas +1

Al final ejecuta el código:

Código SQL [-]
     Update co_detalleconsultas SET
        IDSERVASIG = :sidservasig
     Where co_detalleconsultas.iddetcons = :diddetcons;

Que "Regresa" el sidservasig a al detalle de la consulta (para saber a que control se asignó)
__________________
Sitrico
Responder Con Cita
  #2  
Antiguo 01-06-2007
Avatar de rastafarey
rastafarey rastafarey is offline
Miembro
 
Registrado: nov 2003
Posts: 927
Poder: 21
rastafarey Va por buen camino
Resp

No voy a leer todo el codigo.

Pero si quieres usar recursion no se puede.
__________________
Todo se puede, que no exista la tecnología aun, es otra cosa.
Responder Con Cita
  #3  
Antiguo 01-06-2007
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Que en un trigger after insert ejecute un SP para agregar un registro a otra tabla, lo veo correcto.

Que ese SP modifique la primera tabla, eso ya no me parece lógico. Quizás deberías usar un trigger before Insert, así modificas campos en la primera tabla, y además lanzas la inserción en la segunda.

El SP se supone está compilado... pero no me queda claro eso de hacer 2 inner joins cuando se va a ejecutar en un trigger, quizás fuera mejor usar una vista.
Para este detalle me gustaría que otros foristas opinaran.

Si ya tienes un trigger before insert de la primera tabla y no quieres modificarlo, siempre puedes usar el "position 1"

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #4  
Antiguo 02-06-2007
Avatar de sitrico
[sitrico] sitrico is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Caracas, Venezuela
Posts: 295
Poder: 21
sitrico Va por buen camino
Gracias por las respuestas

Primero debo aclarar que aunque parezca raro: ¡ funciona ! (yo mismo no lo creia)

rastafarey: no es recursión

La idea -simplificada- es: La primera tabla recibe los datos del cliente, luego de insertarlos (after insert) el servidor llama al procedimiento que pasa los datos correspondientes a otra tabla (en este proceso se genera el Nº de ID) y luego se envia (update) el Nº de ID a la primera tabla.

Lepe: La idea de usar el before insert me parece interesante, pero considerando el caso: (la primera tabla guarda el servicio prestado y luego de "prestado el servicio" se llama al SP para que cree la cuenta por pagar) supongo que el resultado final sería el mismo, pero prefiero almacenar primero el servicio y luego crear la deuda.

debo aclarar que no domino mucho la programación del lado del servidor en firebird (es mi 1ra applicación) así que el tema de las vistas ó usar el "position 1" escapan de mis conocimientos ...por ahora
__________________
Sitrico
Responder Con Cita
  #5  
Antiguo 02-06-2007
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Todod el proceso se realiza en una transacción, por tanto, si una de las dos cosas falla, se deshace el proceso completo. Por eso no importa crear primero la deuda que el servicio, aunque como dices, parece lógico hacerlo al revés.

El "position 1" es un parámetro al tiempo de crear varios triggers after insert para una misma tabla, con ese parámetro indicas en qué orden deben ejecutarse esos triggers (no sé si tienes ya un trigger before insert o no).

La vista, échale una ojeada ya mismo. Seguro que tendrás que hacer varios inner joins cuando quieres acceder a las tablas, con la vista, te evitas hacerlos.

Código SQL [-]
Create View vwClientes( 
idcliente,
nombre,
servicio prestado, 
idservicio)

as

select c.idcliente, c.nombre, s.Servicio prestado, s.idservicio
from clientes c inner join servicios s on c.idcliente = s.idcliente

end.
Ya puedes acceder a esta vista como si fuera una tabla más, con la peculiaridad de reunir información de varias tablas al mismo tiempo.

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #6  
Antiguo 04-06-2007
Avatar de sitrico
[sitrico] sitrico is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Caracas, Venezuela
Posts: 295
Poder: 21
sitrico Va por buen camino
Gracias lepe, no conocía las vistas, por lo que te entendí trabajan como una suerte de tabla "virtual", almacenando un select (complejo) para devolver los datos solicitados

Bueno a leer un rato...
__________________
Sitrico
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
No se dispara mas KeyDown con TAB Monchi Varios 0 28-03-2007 17:47:42
Trigger se dispara sin Commit jevo19100 Firebird e Interbase 5 13-03-2007 18:00:09
usando SQLCODE en procedimiento /trigger ASAPLTDA Firebird e Interbase 1 05-01-2006 14:35:41
Evento que se dispara al dar foco nuevamente al 1er form RJF Varios 2 07-12-2005 14:17:52
Ejecutar Procedimiento Almacenado en Trigger AGAG4 SQL 16 21-09-2004 03:27:47


La franja horaria es GMT +2. Ahora son las 03:47:31.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi