Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 28-11-2005
Silvestre Silvestre is offline
Registrado
 
Registrado: nov 2005
Posts: 1
Poder: 0
Silvestre Va por buen camino
Campos Autoincrementables en Paradox

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.
Responder Con Cita
  #2  
Antiguo 29-11-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 31
Lepe Va por buen camino
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
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #3  
Antiguo 29-11-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 31
Lepe Va por buen camino
Código Delphi [-]

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
__________________
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 29-11-2005
Avatar de vtdeleon
vtdeleon vtdeleon is offline
Miembro
 
Registrado: abr 2004
Ubicación: RD & USA
Posts: 3.236
Poder: 26
vtdeleon Va por buen camino
Saludos

Lepe
function NuevoId(D:TTable; campoIncrento:String):Integer; un pequeño error
__________________
Van Troi De León
(Not) Guía, Code vB:=Delphi-SQL, ¿Cómo?
Viajar en el tiempo no es teóricamente posible, pues si lo fuera, ya estarían aqui contándonos al respecto!
Responder Con Cita
  #5  
Antiguo 29-11-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Lepe
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?


Cita:
Empezado por Lepe
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
Responder Con Cita
  #6  
Antiguo 29-11-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Una cosa más sin ánimo de molestar... bueno, un poquito

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
Responder Con Cita
  #7  
Antiguo 29-11-2005
Avatar de marcoszorrilla
marcoszorrilla marcoszorrilla is offline
Capo
 
Registrado: may 2003
Ubicación: Cantabria - España
Posts: 11.221
Poder: 10
marcoszorrilla Va por buen camino
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.
__________________
Guía de Estilo de los Foros
Cita:
- Ça c'est la caisse. Le mouton que tu veux est dedans.
Responder Con Cita
  #8  
Antiguo 29-11-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por marcoszorrilla
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
Responder Con Cita
  #9  
Antiguo 30-11-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 31
Lepe Va por buen camino
Si que se ha montado el pastel

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
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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


La franja horaria es GMT +2. Ahora son las 06:58:33.


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