Como dije más abajo, si, le hago un flush, pero no usé la cláusula force.

Me parece que el tema pasa por el alto volumen de datos que maneja esa rutina. Quizás el campo autoincremental no actúa tan rápido como para procesar todos los registros al mismo tiempo, o sea, no se sincroniza bien con el tableupdate y por eso se corrompe el índice.

Me parece que lo mejor en este caso es usar el viejo sistema de una tabla auxiliar con el último número de PK, compararlo con el valor máximo que tiene la tabla y ponerlo en el campo clave (ya sin la restricción del autoincremental) y luego grabar con el tableupdate.

Lo que no entiendo es por qué sugerís que no lo ponga dentro de una transacción.

Rafael Copquin

El 21/04/2010 19:54, Pablo Pioli escribió:
Si no lo estas incluyendo en una transaccion podria ayudar.
Haces un Flush Force despues?
Pablo Pioli
----- Original Message -----
*From:* Rafael Copquin <mailto:[email protected]>
*To:* GUFA List Member <mailto:[email protected]>
*Sent:* Wednesday, April 21, 2010 6:26 PM
*Subject:* [GUFA] campos autoincrementales y tableupdate

Tengo una aplicación que maneja un laboratorio de cosmética.

Por requerimientos del ANMAT, es necesario que cada caja, frasco, etc. lleve una etiqueta con el número de lote y otros datos que permitan el rastreo de la fecha, hora, lote, orden de fabricación, etc.

Para eso, guardo todos los datos generados en una tabla, que _tiene un campo autoincremental que es a la vez su clave primaria_.

Los datos están en un Windows Server 2003 y las terminales son todas XP Profesional

En el load del formulario genero un cursor adapter vacio para la tabla mencionada, con el siguiente select:

select * from tabladelotes where 1=0

La manera de grabación, dentro de una transacción, es la siguiente:

for I = 1 to nNumeroDeCajas
cNumeroDeLote = 'xxxxxx'+alltrim(str(I)) && no importa el verdadero código del lote, sino que es secuencial como se ve aqui
   insert into (cursoradapter) values( todos los campos + cNumeroDeLote)
endfor
tableupdate(.t.,.t.) && hago el tableupdate al final del loop

Una alternativa sería

for I = 1 to nNumeroDeCajas
    cNumeroDeLote = 'xxxxxx'+alltrim(str(I))
    insert into (cursoradapter) values( todos los campos + cNumeroDeLote)
tableupdate(1,.t.) && un tableupdate por cada registro
endfor

Al final de la transaccion hago un flush para vaciar los buffers a disco

Uso la primera opción.

Mi problema es que casi todos los días se corrompe el índice de esta tabla. Revisé las conexiones, las tarjetas de red, excluí el directorio completo de las tablas, con sus índices, en el antivirus del server, en fin, todo lo que se me ocurrió.

Esta rutina es de grandes volúmenes, porque en una orden de fabricación se pueden generar por ejemplo 1000 frascos de esmalte de uñas y se hacen muchas órdenes por día.

Entonces, la duda que tengo es si, al mandar el tableupdate al final del loop, haciendo que se graben de un saque todos los registros, dado el gran número de ellos y a la vez el hecho de que se genera la clave autoincremental, eso no estará haciendo que se corrompa el índice?

¿alguien tiene alguna idea?

Gracias anticipadas

Rafael Copquin



Responder a