PDA

Ver la Versión Completa : Id Consecutivo en Paradox


Anabel
01-03-2004, 23:41:22
Hola!

Tengo que hacer un Insert en una tabla, pero los registros de está tabla los debo controlar con un ID consecutivo, para saber que ID es el que le corresponde al siguiente registro que voy a Insertar, hago lo siguiente: Ejecuto un Query en la tabla y coloco el cursor en el último registro (TQuery.Last), entonces asigno a una variable el valor del último ID + 1, al realizar el siguiente insert asigno al nuevo ID = último ID+1, es correcto??
Siento que doy muchas vueltas para algo tan sencillo, que me sugieren?
Las tablas están en Paradox.

Gracias :)

eduarcol
01-03-2004, 23:53:42
Es una buena opcion, aunqe si estas trabajndo en Red con el sistema, te recomendaria que llevaras un correlativo, esto lo puedes llevar en un campo de una tabla o en un Archivo .Ini, Este correlativo lo trabajarias antes de postear y no al insertar, porq entre el momento de insertar ypostear otras estaciones estarian trabajando en lo mismo y te alteraria el orden, Harias algo asi en el BeforePost:
1: Leer el Correlativo(Tu decids de donde)
2: Asignarlo
3: Incrementar el Correlativo

Es mas trabajoso pero CREO yo que sera mas seguro. Eso si no te recomiendo los campo autoincrement son un verdadero lio

Anabel
02-03-2004, 00:35:37
Muchas Gracias Eduardo :) ya entendí... sólo que ahora me surgio una inquietud con tu comentario sobre usar un campo autoincrement, ya que en dos de mis tablas utilizo este tipo de campo. Por qué no es confiable este tipo de campo?

Ana :)

jdelphi
02-03-2004, 01:23:36
Por que no mejor utilizar un Autoincremental y que lo controle paradox.
Cuando realice un insert solo envia los valores de todos los campos a insertar exepto el del valor autoincremental.

Ignacio
02-03-2004, 04:16:15
Hola

Quiero aportar mi experiencia con campos autoincrementales. En una aplicación usada simultaneamente por ocho PC, donde todas leen y escriben en la misma base de datos puesta en una de las PC, uso este tipo de campos en todas las tablas y no he tenido problemas (hasta ahora gracias a Dios).

He sentido críticas sobre Paradox y algunas las comparto, pero sobre los campos autoincrementales no.

eduarcol
02-03-2004, 16:05:51
Yo lo digo por mi propia experiencia, al principio los cree, pero por el poco control que tenia sobre ellos no me quedo otra que no usarlos, la mayoria de las fallas eran de diseño pero me encontre en un dilema, o cambiar el diseño o cambiar el tipo de campo, asi que opte por un campo que pudiera controlar :)

Anabel
02-03-2004, 18:13:28
Hola,

Muchas gracias por los comentarios, el campo Autoincremental ya lo he utilizado en otras tablas, pero para el proceso que estoy haciendo no me es funcional, ya que puede haber dos renglones o mas de mi tabla con el mismo id que viendo lo bien talvez ya no es tan correcto llamarlo id, pues se repite :p

Una duda Eduardo, cuando en tip que me diste mencionas: Paso 2) Asignar el correlativo. Significa que debo hacer
a) Insertarlo en la tabla en la que voy a guardar los datos??
b) asignarlo a una variable, que utilizaría posteriormente en el Insert??
Disculpa mi ignorancia, pero ahí no me queda claro que hacer :confused:

Buen día Chicos
Ana :)

eduarcol
02-03-2004, 18:16:19
Pues como dices que varios registros deben llevar ese campo lo deberias colocar en una variable y leerlo desde alli, porq si lo lees desde donde lo tienes guardado de nuevo no te va a servir porq ya estaria incrementado

La mejor solucion es antes de Darle el post, leerlo asignarlo a los distintos registros e incrementarlo

Espero me entiendas :)

Silvestre
28-11-2005, 20:52:51
Hola!,

El problema presentado es más frecuente de lo que parece!. Yo mismo lo he sufrido en mis carnes en una aplicación realizada en Delphi con Paradox 7 que corre en red, tardo dos años en corromper los indices, pero al final lo hizo, que nadie se confie!!.

Utilizaba un campo <codigo> como clave primaria autoincrementable y en cierto momento aperecio el mensaje "key violation", la solución es utilizar como clave primaria un campo gestionado por uno mismo y aumentarlo antes del BeforePost en una tabla a parte..., esto ya lo han explicado claramente en los mensajes previos.

Si alguien tiene ese problema y tiene el campo enlazado con otras bases de datos y por tanto quiere conservar el indice para no destruir la integridad referencial, puede añadir un nuevo campo indice a la tabla de tipo Long Integer con el programa Database Desktop y ejecutar la siguiente consulta SQL:

UPDATE tabla_La_que_sea SET Nuevo_Indice = Codigo (el que estaba corrupto). Después evidentemente habra que cambiar el codigo fuente para utilizar el nuevo indice, gestionado esta vez por nosotros mismos. Mi consejo es que nadie utilice campos autoincrementables en paradox si no quiere tener un disgusto cuando menos los espere!!!.

Silvestre.

Lepe
29-11-2005, 17:55:21
Ignacio esto se debe a la forma de trabajar en esa "empresa", basta con que dos usuario se pongan a crear albaranes a la misma vez para que te salte el error de clave duplicada.

Es mas simple de lo que parece. Usuario A da a Insertar un registro, en este punto Usuario B hace lo mismo (como el A todavía no ha guardado, el albaran de B tendrá el mismo número que el de A); En este momento el segundo que le dé a guardar obtiene el precioso mensaje de Clave Duplicada.

Si se opta porque al insertar un registro, se haga un post automático; en el ejemplo anterior no habría problemas, salvo que el usuario A cambie de parecer y anule el albaran, en este caso, se produce un salto, ya no son correlativos.

Solución: La del primer mensaje propuesto por Anabel y repetir el proceso en el evento BeforePost. (para arreglar todo lo dicho en este mensaje).

Por supuesto, la óptima solución es usar una verdadera BBDD cliente-servidor como Firebird.

saludos

Lepe
29-11-2005, 18:07:37
function NuevoId(D:TTable; campoIncrento:String):Integer;
var T:TQuery;
begin
try
Result:=0;
T := Tquery.Create(nil);
T.DatabaseName := D.DatabaseName;
// demás parámetros que se deba configurar.

// es muy facil equivocarse al pasar el nombre del campo incrementable,
// así que tenemos en cuenta el error.
if d.FindField(campoIncremento)= nil then
raise Exception.Create('El campo '+ campoIncremento +
'no está en la tabla '+ D.TableName;

T.sql.text := 'select '+campoIncremento + ' from '+ D.Tablename +
' order by '+CampoIncremento + ' Desc;'
T.Open;
Result := t.Fields[0].AsInteger + 1;
T.Close;
finally
Freeandnil(T);
end;
end;


Y ya podemos usar nuestra rutina para todas las tablas que queramos.

saludos

vtdeleon
29-11-2005, 19:44:34
Saludos

Lepe
function NuevoId(D:TTable; campoIncrento:String):Integer; un pequeño error :)

roman
29-11-2005, 21:06:15
Ignacio esto se debe a la forma de trabajar en esa "empresa", basta con que dos usuario se pongan a crear albaranes a la misma vez para que te salte el error de clave duplicada.


Pobre Paradox tan vilipendiado. ¿De dónde, por dios, han sacado esto?



Es mas simple de lo que parece. Usuario A da a Insertar un registro, en este punto Usuario B hace lo mismo (como el A todavía no ha guardado, el albaran de B tendrá el mismo número que el de A); En este momento el segundo que le dé a guardar obtiene el precioso mensaje de Clave Duplicada.


Prueba hecha ahora mismo, y no hay ningún error de clave duplicada. ¿Qué no estamos hablando de autoincrementales? Paradox no asignará el valor del autoincremental sino hasta el momento de hacer el post, y en ese momento bloquea la tabla para evitar colisiones.

// Saludos

roman
29-11-2005, 21:29:20
Una cosa más sin ánimo de molestar... bueno, un poquito :p

El método usando la función NuevoId, me parece que fallará más rápido que el autoincremental. La tabla debe bloquearse antes de leer el id y desbloquearse después de asignar el id. O si no, explíquenme qué sucede en la misma situación descrita por Lepe. El usuario A inserta un registro pero no hace el post. Lo mismo hace B. Ambos leen el NuevoId, que será el mismo para ambos si no han hecho el post.

// Saludos

marcoszorrilla
29-11-2005, 23:09:40
Yo ya he comentado algunas veces que utilizo una tabla auxiliar en donde guardo el último número de Albarán.

A los usuarios les atribuyo un número (1,2,3...) y cada usuario que empiece a crear un albarán multiplico su número por 100, el 1=100 el 2=200....
Al último albarán, le sumo este número, de tal manera que puece haber varios usuarios creando un albarán, sin confirmar y todos tendrán número distinto, este número es provisional, si lo cancelan pues cancelamos todo y no pasa nada, pero si deciden grabar, ponen la tabla contador en modo edición, si lo logran, esta queda bloqueada momentaneamente, le suman 1 al número y graban el albarán liberando la tabla contador despues de haber aumentado en uno el último número(milésimas de segundo).

Un Saludo.

roman
29-11-2005, 23:21:04
ponen la tabla contador en modo edición, si lo logran, esta queda bloqueada momentaneamente, le suman 1 al número y graban el albarán liberando la tabla contador despues de haber aumentado en uno el último número(milésimas de segundo).

¡Exacto! El bloqueo sólo es necesario (pero imprescindible) durante el infinitésimo que se toma leer el número y grabarlo.

Conste que esto sólo es necesario para no dejar huecos en la secuencia, para lo cual ciertamente no sirven los autoinc, pero no porque fallen.

Por cierto Marcos, muy inteligente eso de mutpilcar al usuario por cien.

// Saludos

Lepe
30-11-2005, 18:04:56
Si que se ha montado el pastel :p

Simplemente se llama a mi rutina en el evento OnNewRecord, (que gracias a vtdeleon queda claro que no he compilado), despues en el BeforePost se vuelve a llamar y listo.

El primero que grabe, se queda con el número que tiene en pantalla, el último usuario, verá como su númerito se actualiza, y siempre serán números correlativos.

Si se quiere más seguridad, en el OnNewRecord no se hace nada, su dbedit de solo lectura se quedará en blanco, y en el BeforePost se llama a la rutina. De esta forma, únicamente al grabar se verá el número que le corresponde.

saludos

roman
30-11-2005, 18:42:27
despues en el BeforePost se vuelve a llamar y listo.

El primero que grabe, se queda con el número que tiene en pantalla, el último usuario, verá como su númerito se actualiza, y siempre serán números correlativos


El punto no es donde lo llames, sino el hecho de que al no bloquear la tabla durante la lectura y grabado del id, con múltiples accesos simultaneos siempre cabe la posibilidad de que dos lean el mismo número y por tanto intenten grabar el mismo correlativo.

// Saludos

marcoszorrilla
30-11-2005, 18:47:35
Tampoco interesa que haya dos albaranes con el mismo número aunque sea sin grabar, ya que en el momento que crees dos líneas de albarán(detalle) se hace un "post" automático y estas líneas pudieran quedar asociadas a otras 2 que está grabando otro usuario con el mismo número.

Un Saludo.

Lepe
01-12-2005, 08:44:24
Lo comentado por roman es cierto.

Lo comentado por Marcos, bueno, en mi caso no hay lineas de albaran.


saludos