Club Delphi  
    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 16-09-2004
Tecnic2 Tecnic2 is offline
Miembro
 
Registrado: may 2004
Posts: 155
Poder: 20
Tecnic2 Va por buen camino
Question Algun consejo para copiar datos?

Hola, estoy haciendo una aplicacion que tiene que coger tablas .dbf y copiar todos sus registros en tablas .mdb.
Obtengo los datos de las tablas .dbf con un TADOQuery y las .mdb con un TTable.
Pues bien, el principal problema es que el total de registros a copiar es de 400.000 aproximadamente, y tarda más de 30 minutos en completar el traspaso.
Lo que quiero es saber si hay alguna otra forma de hacerlo para ir más rápido a parte de la que yo utilizo.

Ésta es la funcion para copiar una de las tablas:

procedure TFAssistent.VolcarAlbfaccp();
begin
ADOQueryAux.Close;
ADOQueryAux.SQL.Clear;
ADOQueryAux.SQL.Add('SELECT fecfac, codpro, ejefac, numfac');
ADOQueryAux.SQL.Add('FROM albfaccp');
ADOQueryAux.Open;

while (n_regs <= ADOQueryAux.RecordCount -1) do
begin
inc(n_regs);
lInfo2.Caption := 'Registro: ' + IntToStr(n_regs) + ' de ' + FloatToStr(ADOQueryAux.RecordCount);
BarraProgreso.Position := n_regs;
TAccessDatos.Insert;
TAccessDatos.FieldByName('fecfac').AsString := ADOQueryAux.Recordset.Fields.Item[0].Value;
TAccessDatos.FieldByName('codpro').AsString := ADOQueryAux.Recordset.Fields.Item[1].Value;
TAccessDatos.FieldByName('ejefac').AsString := ADOQueryAux.Recordset.Fields.Item[2].Value;
TAccessDatos.FieldByName('numfac').AsString := ADOQueryAux.Recordset.Fields.Item[3].Value;
TAccessDatos.Post;
ADOQueryAux.Recordset.MoveNext;
end;
end;

Muchas gracias.
Responder Con Cita
  #2  
Antiguo 16-09-2004
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.233
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por Tecnic2
...que tiene que coger tablas .dbf y copiar todos sus registros en tablas .mdb.
Obtengo los datos de las tablas .dbf con un TADOQuery y las .mdb con un TTable.
¿Pq no usas ADOTAble para las tablas de Access? Justamente ADO es el driver de MS para BD de MS (aunque luego sirva para muchas otras).

Desactiva controles visuales "ligados" a los Datasets (si es que tienes alguno).

Podrías probar a crear los índices en la tabla destino al acabar (si no son necesarios para comprobaciones), eso aceleraría las inserciones.

FieldByName tardará más que FieldByIndex; Como no va a cambiar el orden, mira cual es ese el orden y accede a los campos por índice.

Ya se que el tema de la barra de progreso y el label es necesario, pero intenta que el refresco no sea cada registro, sino cada 500 registros (por ejemplo), al usuario le sigue dando info. y tú te evitas muchos refrescos.

ADOQueryAux.RecordCount es un valor fijo, sácalo del bucle a una variable y no lo calcules cada vez (tanto el de la línea del while, como el que hay dentro).

Si puedes hacer éstos cambios, a ver si baja bastante... (infórmanos )
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 16-09-2004
Tecnic2 Tecnic2 is offline
Miembro
 
Registrado: may 2004
Posts: 155
Poder: 20
Tecnic2 Va por buen camino
Question Pregunta

Ya he probado lo del RecordCount y he reducido 10 minutos. Ahora estoy probando poner el TADOTable pero no veo la propiedad "FieldByIndex". Es que no la he buscado bien?

Gracias.
Responder Con Cita
  #4  
Antiguo 16-09-2004
CHiCoLiTa CHiCoLiTa is offline
Miembro
 
Registrado: may 2003
Posts: 102
Poder: 21
CHiCoLiTa Va por buen camino
creo que se refiere a Field[0] en vez de FieldByName('fecfac'), que en ver por nombre, accedas por la posicion de campo
Responder Con Cita
  #5  
Antiguo 17-09-2004
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.233
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por CHiCoLiTa
creo que se refiere a Field[0] en vez de FieldByName('fecfac'), que en ver por nombre, accedas por la posicion de campo
Correcto, a eso me refería. Gracias. Lo dije de memoria y ya se sabe, a veces juega malas pasadas...

El tema de los controles visuales (no refrescar cada registro, sino cada 500, por ejempo) creo que también te hará bajar bastante; junto con los índices en la tabla destino (si es posible).

Una última cosa que se me ocurre (aunque no se si bajará mucho el tiempo) es utilizar un ADOQuery/ADOCommand para insertar en lugar de un ADOTable; En ese caso se puede "jugar" con las propiedades Prepared(False), ExecuteOptions(eoExecuteNoRecords), CursorType(ctOpenForwardOnly),... y tal vez alguna más...

Lo dicho, sigue informándonos de los resultados, ya que es tema que interesa.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #6  
Antiguo 17-09-2004
Tecnic2 Tecnic2 is offline
Miembro
 
Registrado: may 2004
Posts: 155
Poder: 20
Tecnic2 Va por buen camino
Question Problemas con ADO, URGENTE!

Tengo la siguiente funcion para abrir la conexion ADO de enlace con las tablas access destino, pero me da error. PORQUE!!!

procedure TFAssistent.ObreADO();
begin
ADOConnexioAccess.ConnectionString := 'Provider=MSDASQL.1;' +
'Persist Security Info=False;' +
'Extended Properties="DSN=WingestControl;' +
'DBQ=C:\Dades\WingestControl\ANCORA\dades.mdb;' +
'DriverId=25;' +
'FIL=MS Access;' +
'MaxBufferSize=2048;' +
'PageTimeout=5;' +
'UID=admin;"';
ADOConnexioAccess.Connected := True;
ADOTAccessDades.Active := True;
end;
Responder Con Cita
  #7  
Antiguo 17-09-2004
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Hola Tecnic.

Te pido que leas la guia de estilo de los foros, debido a que has puesto una nueva pregunta que nada tiene que ver con este hilo (aún cuando lo hayas iniciado vos).

También te pido que aprendas a usar la etiqueta [delphi] para publicar trozos de código, correctamente indentados y con la sintaxis resaltada. De la manera que están publicados realmente se hace dificil su lectura.

Por último, te refiero al hilo de la calidad de las preguntas; espero que al leerlo vos mismo entendas porque.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #8  
Antiguo 20-09-2004
Tecnic2 Tecnic2 is offline
Miembro
 
Registrado: may 2004
Posts: 155
Poder: 20
Tecnic2 Va por buen camino
Thumbs up Lo siento, perdonad las molestias.

Siento no haber leido la guia de estilo.
Con los controles ADO ya ve copia los datos mucho mas rapido.
Muchas gracias.
Responder Con Cita
  #9  
Antiguo 20-09-2004
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.233
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
¿En cuanto tiempo ha quedado la cosa al final? (sólo por curiosidad)
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #10  
Antiguo 20-09-2004
Tecnic2 Tecnic2 is offline
Miembro
 
Registrado: may 2004
Posts: 155
Poder: 20
Tecnic2 Va por buen camino
Estoy en ello.

En cuanto haya hecho las pruebas suficientes os lo digo.
Responder Con Cita
  #11  
Antiguo 20-09-2004
Tecnic2 Tecnic2 is offline
Miembro
 
Registrado: may 2004
Posts: 155
Poder: 20
Tecnic2 Va por buen camino
Question Mas problemas

Tengo el siguiente código dentro de un bucle para escribir datos en la tabla destino, pero no me guarda los datos, aunque no me da ningún error:
ADOQueryAux és un objeto TADOQuery en el que hay datos, ADOTAccessDades és una tabla ADO ligada a un objeto TADOConnection en el que hay un connection string hacia la base de datos destino.

ADOTAccessDades.Insert;
ADOTAccessDades.Fields[0].Value := ADOQueryAux.Recordset.Fields.Item[0].Value;
ADOTAccessDades.Fields[1].Value := ADOQueryAux.Recordset.Fields.Item[1].Value;
ADOTAccessDades.Fields[2].Value := ADOQueryAux.Recordset.Fields.Item[2].Value;
ADOTAccessDades.Fields[3].Value := ADOQueryAux.Recordset.Fields.Item[3].Value;
ADOTAccessDades.Post;
ADOQueryAux.Recordset.MoveNext;

Por qué no me guarda los registros?
Responder Con Cita
  #12  
Antiguo 20-09-2004
Tecnic2 Tecnic2 is offline
Miembro
 
Registrado: may 2004
Posts: 155
Poder: 20
Tecnic2 Va por buen camino
Question Dos cosillas....

Primera: Como hago lo de los índices en las tablas destino?
Segunda: Las propiedades que mencionas al usar un ADOQuery en lugar de un ADOTable tienen que estar en los valores que has escrito exactamente?

Millones de gracias.
Responder Con Cita
  #13  
Antiguo 20-09-2004
Tecnic2 Tecnic2 is offline
Miembro
 
Registrado: may 2004
Posts: 155
Poder: 20
Tecnic2 Va por buen camino
Post Test de velocidad

Tengo ya el programa probado con controles ADO y aparentemente no se aprecia ningún cambio en cuanto a lo que a velocidad se refiere.
No sé si será por algo que me falta o qué, pero parece que no hay cambio alguno.

Mas consejos?
Responder Con Cita
  #14  
Antiguo 21-09-2004
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.233
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por Tecnic2
Primera: Como hago lo de los índices en las tablas destino?
Se trata de NO crear los índice al cear la tabla, luego hacer las inserciones y finalmente crear los índices. Al final puedes crear los indices utilizando SQL con un ADOQuery. Ésto no siempre es posible, ya que a veces interesa que los índices estén creados (para evitar duplicaciones, por ejemplo), pero si sólo vas a copiar los datos de una tabla que ya está correcta, tal vez te sirva. El problema, es que si tienes una tabla con 3 índices (por ejemplo), cada vez que haces un insert la Tabla, la BD debe "regenerar" esos tres índices, cuando en realidad bastaría hacerlo una única vez al final (de ahí lo de crearlos al final).

NOTA: Creo que ésta opción de los índices, si puedes hacerla, tb acelerará bastante.


Cita:
Empezado por Tecnic2
Segunda: Las propiedades que mencionas al usar un ADOQuery en lugar de un ADOTable tienen que estar en los valores que has escrito exactamente?
En principio sí (aunque no las puedo probar), Prepared(False) es el valor por defecto para que ADO no prepare la consulta, ExecuteOptions(eoExecuteNoRecords) para que ADO no espere registros de vuelta ya que es un Insert y CursorType(ctOpenForwardOnly) si no deseas hacer recorridos en dos direcciones por el Dataset, ya que tiene mejor rendimiento (y en tu caso no los necesitas, ya que sólo vas a hecer recorrido simple en una dirección).
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #15  
Antiguo 21-09-2004
Tecnic2 Tecnic2 is offline
Miembro
 
Registrado: may 2004
Posts: 155
Poder: 20
Tecnic2 Va por buen camino
Question Cómo creo los índices desde código?

Muchas gracias por tu respuesta Neftali.

Mi problema surge cuando establezco esos parámetros en mi control ADOQuery, me da un error de incompatibilidad, o algo así, entre éllos.

Por otra parte, cómo lo hago para crear los índices de las tablas desde código? Además, no entiendo por que tendría que acelerar el traspaso de datos el crear los índices al final si precisamente al final los datos ya están copiados.

Otra vez, gracias por adelantado.
Responder Con Cita
  #16  
Antiguo 21-09-2004
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.233
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por Tecnic2
...Mi problema surge cuando establezco esos parámetros en mi control ADOQuery, me da un error de incompatibilidad, o algo así, entre éllos.
Ok, pruébalos sólo en el ADOTAble que está contra el Access. De todas formas si alguno te da problemas, pues decartalo y vuelve a la opción por defecto, sólo era para probar mejoras.

Cita:
Empezado por Tecnic2
Por otra parte, cómo lo hago para crear los índices de las tablas desde código?
Busca en access ayuda sobre CREATE INDEX, y utilizando un ADOQuery con la sentencia; Por ejemplo:

Código SQL [-]
CREATE INDEX I_Nombre ON Clientes (Nombre ASC)

te crea un índice en la tabla Clientes ascendente por el campo nombre.

Cita:
Empezado por Tecnic2
Además, no entiendo por que tendría que acelerar el traspaso de datos el crear los índices al final si precisamente al final los datos ya están copiados.
Justo por eso, los índices son buenos para acelerar las búsquedas en una tabla, pero ralentizan las inserciones/modificaciones/borrados porque cada vez que haces una de éstas operaciones el índice se regenera. Para que me entiendas, en una inserción no se usa un índice (con la excepción de que controles duplicados con ellos), por lo tanto si haces 1000 inserciones seguidas, los único que hace la BD es, depués de cada inserción "regenerar" el índice por si le hacen una consulta.

El resultado de hacer:
Código:
INSERT1
 (la BD regenera el índice)
INSERT2
 (la BD regenera el índice)
INSERT3
 (la BD regenera el índice)
INSERT4
 (la BD regenera el índice)
...
INSERT1000
 (la BD regenera el índice)
y hacer ésto:

Código:
INSERT1
INSERT2
INSERT3
INSERT4
...
INSERT1000
 (crear el índice)
para tu caso concreto es lo mismo ya que en todo éste proceso el índice no se usa para nada (con la excepción de que controles duplicados con ellos, como ya te he dicho)
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #17  
Antiguo 21-09-2004
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
Tecnic2:

Estuve haciendo unas pruebas ayer transfiriendo 600,000 registros de una tabla dbase a una tabla access. Para dbase usé un TTable anque usar un Query no creo qe cambie mucho los resultados, y para Access use un TAdoTable.

Tal como sugiere Neftalí la tabla de Access no tenía índices al momento de la transferencia.

En la primera prueba, copiando registro a registro tal como lo has hecho, el tiempo de transferencia total fue, digamos, infinito (no esperé ni con mucho a que terminara ).

Luego de jugar con varias propiedades observé un cambio drástico con dos de ellas:

Una, ya te la comentaron: CursorType := ctOpenForwardOnly
La otra, CursorLocation := clUseServer

Con estas dos, el tiempo total de transferencia fue de entre 4 y 5 minutos.

// Saludos
Responder Con Cita
  #18  
Antiguo 21-09-2004
Tecnic2 Tecnic2 is offline
Miembro
 
Registrado: may 2004
Posts: 155
Poder: 20
Tecnic2 Va por buen camino
Question Y cómo lo haces?

Tienes un bucle que recorre todos los registros normal y corriente? Me puedes pasar el código de ejemplo a ver si hay algo que hago mal?

Muchas gracias.
Responder Con Cita
  #19  
Antiguo 21-09-2004
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
Te digo que es similar a lo que estás haciendo tú:

Código Delphi [-]
{
  Table1 - TTable para dbase
  AdoTable1 - TAdoTable para Access
}

  Button1.Enabled := false;
  Done := false;

  Table1.Open;
  AdoTable1.Open;

  while not Table1.Eof and not Done do
  begin
    Application.ProcessMessages;

    with AdoTable1 do
    begin
      Append;

      Fields[0].AsString := Table1.Fields[0].AsString;
      Fields[1].AsString := Table1.Fields[1].AsString;
      Fields[2].AsDateTime := Table1.Fields[2].AsDateTime;
      Fields[3].AsString := Table1.Fields[3].AsString;
      Fields[4].AsString := Table1.Fields[4].AsString;
      Fields[5].AsString := Table1.Fields[5].AsString;
      Fields[6].AsString := Table1.Fields[6].AsString;
      Fields[7].AsString := Table1.Fields[7].AsString;
      Fields[8].AsString := Table1.Fields[8].AsString;
    end;

    Table1.Next;
  end;

  if AdoTable1.State = dsInsert then
    AdoTable1.Post;

  Button1.Enabled := true;
  Done := true;

El decrecimiento radical lo obtuve con las dos propiedades que te menciono.

// Saludos
Responder Con Cita
  #20  
Antiguo 21-09-2004
Tecnic2 Tecnic2 is offline
Miembro
 
Registrado: may 2004
Posts: 155
Poder: 20
Tecnic2 Va por buen camino
ADO ha funcionado

He visto la luz...
Me faltaban establecer las propiedades CursorType y CursorLocation, a parte de lo de preguntar lo del State.

He pasado de hora y media a 4 minutos y medio.

Millones de 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 09:07:09.


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