Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 25-09-2012
mjjj mjjj is offline
Miembro
 
Registrado: mar 2007
Posts: 652
Poder: 18
mjjj Va por buen camino
Reglas de registros en BD Firebird

Amigos de foro, después de ya haber desarrollado varias aplicaciones, las cuales cada vez se conectan mas usuarios, me ha surguido una duda.

Utilizo Firebird 2.5 y Delphi 2010.
Imaginemos la siguiente situación, un usuario realiza una consulta a la BD, la cual tiene implicita condiciones para evitar problemas, por ejemplo: todas las facturas tal que no estén en nómina, sería algo así:

Código SQL [-]
select f.* from facturas f left join nomina n on f.id_factura = n.id_factura where n.id_factura is null

Ahora pensemos que un segundo usuario realiza la misma consulta, previamente a que el primer usuario inserte, modifique o elimine algún registro que cambie el resultado de la consulta. Es decir, ambos usuario tienen los mismo resultados (en este caso facturas) que cumplen con la condiciones de no estar en alguna nomina.

Seguido a esto el segundo usuario asocia cierta factura (por ejemplo la numero 3) a una nomina.
Si es que el primer usuario NO refresca la consulta, e intenta asociar la misma factura 3 a una nómina tendré una duplicidad y posterior problemas con esto.

No puedo resolver esto, sin tener que refrescar la cunsulta antes de insertar, modificar o eliminar el registro?

Se puede programar condiciones (reglas) en el mismo motor de BD?
Como se hace esto?
Algun link de donde aprender?

Espero me puedan ayudar.
Gracias
Responder Con Cita
  #2  
Antiguo 25-09-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.078
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Si el usuario1 saca un listado de las nóminas sin factura.
Al mismo tiempo, el usuario2 está asociando una factura a una de esas nóminas.
El informe del usuario1 dirá que la nómina xxx no tiene factura, cuando realmente ya sí que la tiene.
Pero es que ahí no hay nada mal, ya que cuando pidió el listado, esa nómina no tenía factura.

¿Te refieres a eso?
Responder Con Cita
  #3  
Antiguo 25-09-2012
mjjj mjjj is offline
Miembro
 
Registrado: mar 2007
Posts: 652
Poder: 18
mjjj Va por buen camino
Es solo un ejemplo con facturas y nomina, en la realidad es mucho mas complejo.

Los dos usuario sacan un listado de las facturas sin nómina, el usuario1 asocia la factura 2, a la nomina 5, esta significa que si vuelvo a sacar el listado de las facturas sin nomina no aparece la factura 2. Sin embargo, si el usuario2 no vuelve a solicitar la lista, en la lista actual (la primer lista que solicitaron), aun aparece la factura 2.
En este caso, si el usuario asocia la factura 2 a la nomina x, se duplicara la factura 2 en la tabla nomina.

Espero se haya entendido mejor.
Responder Con Cita
  #4  
Antiguo 25-09-2012
mjjj mjjj is offline
Miembro
 
Registrado: mar 2007
Posts: 652
Poder: 18
mjjj Va por buen camino
Casimiro, creo que este ejemplo en particular lo puedo resolver definiendo claves unicas en Firebird, con esto evito que se duplique la factura en la tabla nomina.

Como expuse anteriormente, esto es solo un ejemplo. En la realidad si pudiese darse que una factura este en dos nomina distintas, pero en este caso la condicion sería que la sumatoria de los montos de la tabla nomina no puede ser mayor a el valor de la factura.

Las tablas estan difinidas como sigue:

Facturas:
-id_factura
-rut
-total
...

Nomina
-id_nomina
-id_factura
-monto
...

Si llevamos esto a SQL, para listar las facturas que no tienen nomina, o que su monto en monina sea menor que el monto de la fatura, lo realizo con un procedimiento almacenado.

Código SQL [-]
for select f.id_factura, rut, total from facturas into :id_factura, :rut, :total do
begin
select sum(monto) monto_total from nomina where id_factura =:id_factura
into : monto_total
suspend;
end

Donde id_factura, rut, total y monto_total son parametro de salida.

De esta forma aparecería la factura 2, si es que la sumatoria de los montos en la nomina es menor que el total de la factura.

Sin embargo, sigue el problema original, en caso de tener 2 o más usuario intentanto asociar la misma factura a una nomina, previmente con el mismo listado.

Con la clave unica no puedo resover esto.
Alguna idea?
Responder Con Cita
  #5  
Antiguo 25-09-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.078
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por mjjj Ver Mensaje
Sin embargo, sigue el problema original, en caso de tener 2 o más usuario intentanto asociar la misma factura a una nomina, previmente con el mismo listado.
Tendrás que comprobar antes si ya ha sido guardada.
También puedes declarar el campo id_factura en la tabla Nomina como "unique" y así saltará una excepción porque no puede repetirse.
Porque se supone también, digo yo, que ese campo es clave foránea de la tabla facturas, ¿no?

Pero si dos personas (o más) están haciendo el mismo trabajo y con un listado "en la mano" es normal que ese listado esté obsoleto incluso antes de salir de la impresora. El programa debe controlar todas esas posibilidades.
Responder Con Cita
  #6  
Antiguo 25-09-2012
mjjj mjjj is offline
Miembro
 
Registrado: mar 2007
Posts: 652
Poder: 18
mjjj Va por buen camino
Efectivamente id_factura es clave foranea en la tabla nominas, pero no puedo hacerla unica, ya que existe la posibilidad que una factura este en mas de una nomina, siempre y cuando la sumatoria de los montos en la tabla nomina no sea superior que el total de la factura.

La ultima parte sel "listado en la mano", no entendí lo de hacerlo absoleto... como puedo hacer/controlar esto?
Responder Con Cita
  #7  
Antiguo 25-09-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.078
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Lo que quería decir es que si un usuario saca un listado de nóminas (por ejemplo) y va un momento a por un café, cuando vuelva, en 5 minutos, ese listado ya puede estar obsoleto porque otro usuario ha podido hacer modificaciones en los datos, por lo que el usuario1 tiene ya un listado "obsoleto".

Creo que en tu caso no te queda otra que comprobar que no exista ya, antes de grabar.
Responder Con Cita
  #8  
Antiguo 26-09-2012
mjjj mjjj is offline
Miembro
 
Registrado: mar 2007
Posts: 652
Poder: 18
mjjj Va por buen camino
es exactamente lo que me temia... me gustaria evitar tener que realizar una consulta justo antes de insertar.

Existe alguna forma de bloquear el registro de este "tomado" por algun usuario, a lo mejor con alguna propiedad de la transaccion?

Otra alternativa, programar en la capa de la BD, quizas con el algún trigger, la idea es evitar esto en la capa del interfase con el usuario.

Como se manejan estas situaciones por regla general?

Salu2
Responder Con Cita
  #9  
Antiguo 26-09-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.078
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
No entiendo bien el funcionamiento del sistema, pero ¿puede existir en la tabla Nomina dos registros con id_nomina, id_factura repetidos?
En caso contrario puedes crear un índice id_nomina+id_factura y que no admita repetidos.
Responder Con Cita
  #10  
Antiguo 26-09-2012
mjjj mjjj is offline
Miembro
 
Registrado: mar 2007
Posts: 652
Poder: 18
mjjj Va por buen camino
eso es exactamente como es la clave primaria: id_nomina-id_factura, lo que si se puede repetir es id_factura en la tabla nomina, ya que puede haber una factura en mas de una misma nomina.
Responder Con Cita
  #11  
Antiguo 26-09-2012
mjjj mjjj is offline
Miembro
 
Registrado: mar 2007
Posts: 652
Poder: 18
mjjj Va por buen camino
Ayer me quede hasta hartas horas de la noche investigando como resolver esto.
Finalmente encontre un documento que explica como utilizar trigger y excepcion para incluir restriccionos directamente en la BD.
De esta forma ya no es necesario verificar por parte del cliente el las restricciones, sino que lo verifica la misma BD.
Espero que a alguien le sirva, dejo el link de descarga.

http://www.firebird.com.mx/imagenes/...esde_la_bd.pdf

Saludos.
Responder Con Cita
  #12  
Antiguo 26-09-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.078
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Está bien que te sirva, aunque no le veo mucha relación con este tema
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
Nuevas Reglas de la RAE marcoszorrilla La Taberna 13 15-11-2010 18:56:01
Las 11 reglas de la vida (Bill Gates) Casimiro Notevi La Taberna 14 12-11-2010 19:27:28
Un ejemplo de reglas de negocio CORBATIN Conexión con bases de datos 5 03-04-2005 01:28:20
OutLook con reglas cmgenny Windows 0 18-08-2003 21:18:13
Ejemplo de reglas en capa intermedia Ulises Conexión con bases de datos 7 07-08-2003 14:08:12


La franja horaria es GMT +2. Ahora son las 04:21:19.


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