PDA

Ver la Versión Completa : Actualización números de factura


Marina
08-05-2003, 15:09:51
Hola a todos!

Trabajo con Interbase 6, Delphi 4 Professional, conexión a través del BDE y CachedUpdates.

La aplicación se ejecuta en red y desde dos puestos de trabajo están facturando al mismo tiempo, el problema lo tengo al generar el número de la factura, el cual debe ser correlativo y por supuesto diferente en los dos puestos. No puedo usar generadores para obtener el número debido a que los tipos de comprobante son variables. Lo que tengo es una tabla con los tipos de comprobante y para cada tipo existe un campo donde se guarda el último número emitido; tengo que sumar 1 a este número y asignárselo al comprobante.
A su vez, el tipo y número de comprobante son los campos clave en el archivo de comprobantes. Este número tengo que grabarlo también en otra tabla relacionada pero que no tiene foreign key.

El problema que estoy teniendo es que desde los dos puestos se genera el mismo número y da el error Key violation.

Alguna ayudita, por favor.

Desde ya muchas gracias

Marina

kinobi
08-05-2003, 15:38:43
Hola,

Posteado originalmente por Marina
El problema que estoy teniendo es que desde los dos puestos se genera el mismo número y da el error Key violation.

una posible solución, de entre varias, sería capturar la excepción que se produce al hacer el post. En caso de ser una "key violation" (y lo sabes por el código de error de la excepción), puedes lanzar otra consulta para obtener un nuevo número e intentar repetir la inserción.

Saludos.

lafirma
08-05-2003, 21:19:53
Oye, porque no usas mejor un generador para cada tipo de comprobante? denro de un trigger beforeinsert puedes establecer el valor dependiendo del tipo de comprobante que estas insertando, asi te evitaras problemas con el uso de campos para ese fin.

kinobi
09-05-2003, 19:22:50
Hola,

la función de los generadores es justamente la inversa: garantizan que no se producirán duplicados de claves, y en consecuencia que no habrá "Key violations", pero no garantizan una secuencia correlativa.

En pocas palabras, en un entorno multi-transacción (InterBase) es imposible conseguir una secuencia correlativa de enteros y que además no se puedan producir errores de claves duplicadas.

Saludos.

Chaja
21-07-2005, 14:35:38
Hola:
Me enganche en este hilo buscando otra coas y bueno.
Mira yo tenia el mismo problema. Por lo pronto yo no uso como clave primaria el mismo numero del comprobante, si no que uso un id interno, que lo tomo de un generador, tanto en la cabecera como en las lineas. Ese Id que es un Integer lo uso como PK. Los numero de comprobantes lo tomo de una tabla que tiene (igual que vos) de un campo de numero el cual leo y le sumo uno. Cuando dos puesto de trabajo hacen el mismo tipo de comprobante, no me afecta ya que los dos tiene un id diferente y no hay conflictos, pero si van a tener el mismo numero de comprobante. Entonces en el momento de hacer un commit en la base de datos en el BeforePost hago una consulta de la tabla de comprobantes donde esta el numero de comprobante, si el numero difiere en el numero mas uno listo lo gravo pero si el otro gravo antes que yo la diferencia va ser menor ya que cuando gravo el comprobante actualizo el campo de numero con el ultimo ingresado. re-actualizo el numero de factura y vuelvo actualizar el numero de comprobante en la tabla de comprobantes. y dejo que grave.
No se si me entendistes.. cualquier cosa laromdp@infovia.com.ar

chau

jam
21-07-2005, 15:08:10
Chaja tiene razón, el nº de factura no debe ser la clave primaria, y para generarlo se pueden utilizar varios métodos, yo el que uso es mediante un disparador que se activa al guardar los datos en el servidor, (cuando se ha confirmado la inserción del registro), luego hago un refresh y recupero el nº de factura.
Antes almacenaba el último número en una tabla, pero ahora lo que hago es obtenerlo con la consulta:
select max(n_factura)+1 from facturas
No se si el maestro Kinobi tiene un método mejor.

marcoszorrilla
21-07-2005, 16:55:09
Pues yo creo que el número de factura ha de ser clave única, otra cosa es como obtener ese número único en el momento de la grabación.

Yo utilizo una tabla auxiliar y en el evento beforeInsert:
1º.- Pongo en edición el último número que es un campo de esta tabla auxiliar,, con lo cual garantizo que no pueda acceder nadie a él en ese momento.
2º.- Le sumo 1 y lo libero

Ahora ya tengo un número único para la factura que se está grabando, la consulta le veo un problema, si se da la casualidad que dos puestos acceden a hacer la consulta al mismo tiempo obtendrán el mismo número de factura.

Un Saludo.

kinobi
21-07-2005, 17:13:46
Hola,

Pues yo creo que el número de factura ha de ser clave única,...

Estoy de acuerdo, no consigo recordar ningún caso en que una factura (entendido como un documento con valor contable) pueda tener un identificador duplicado. Ahora bien, también estoy en la tesis que se comenta anteriormente: el identificador (o número) de factura debe ser único (clave alternativa), pero no clave primaria. Las claves primarias no deberían tener valor semántico en el modelo de datos.

Saludos.

marcoszorrilla
21-07-2005, 18:00:42
De acuerdo, en donde digo clave única = Indexado sin duplicados en algunos contextos, porque como muy bien apuntas el número de factura debe de ser único.

Un Saludo.

jam
21-07-2005, 21:25:02
Estoy de acuerdo con Kinobi, se me olvidó comentar que tengo un índice secundario asociado al nº de factura y si se intenta insertar un valor que ya existe se produce una excepción. Mi programa la captura y vuelve a intentarlo hasta que no se de ningun error.