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 Temas de Hoy

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-09-2004
Avatar de sitrico
[sitrico] sitrico is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Caracas, Venezuela
Posts: 295
Poder: 22
sitrico Va por buen camino
Convertir una tabla paradox a DBF

Buenas,

Tengo una aplicación que incluye un formulario que le permite al usuario importar y/o exportar datos desde la aplicación.

En la aplicación uso tablas paradox (con tQuery) y estoy tratando de convertir la tabla al formato DBase III+ (dbf).

He probado de todo, los componentes DataToDBF, Crear la tabla dbf por código, y algunas rutinas de exportación de datos (bajadas de internet) que usan batchmove. El resultado casi siempre es el mismo: un archivo DBase con datos pero con la estructura incompleta (faltan las definiciones de campos "Number" con sus enteros y decimales)

¿ Alguien me puede decir como se crea un archivo DBase por código ?(preferiblemente usando SQL)
__________________
Sitrico
Responder Con Cita
  #2  
Antiguo 08-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
El tipo Number en Paradox corresponde al campo Float y Dbase III+ no tiene campos de punto flotante. Si te fijas ni siquiera el Database Desktop lo puede hacer:

New table|DBase III+|Borrow... (desde una tabla Paradox)

y sucederá lo mismo que ya has visto, aparecen los campos pero sin tipo de datos.

Esto no necesariamente quiere decir que no se pueda hacer la exportación. Lo que sucede es que el único tipo de datos numérico (enteros o con decimales) que acepta DBase III+ es NUMBER que no es otra cosa que un BCD y los BCD sólo aceptan un número fijo de decimales. Como en un tipo de datos Float no hay forma inherente de determinar cuántos decimales maneja (por algo es punto flotante), utilerías como el Database Desktop no tienen forma de saber cuántos especificar para hacer la conversión.

Sin embargo, a menos que trabajes con cálculos de precisión astronómica , es muy posible que puedas saber de antemano el número máximo de decimales que vas a tener en tu tabla Paradox.

Si por ejemplo, sabes que tus valores tendrán un máximo de 3 decimales con una precisión de 7 (es decir 7 es el mayor número de digitos contando parte entera y parte decimal) entonces puedes usar un campo NUMBER (BCD) especificando 7 como precisión y 3 como decimales (quizá debas especificar 9 en lugar de 7 ya que creo que DBase requiere dos dígitos para almacenar el punto y el signo).

Ya en la práctica, lo que haría es definir yo mismo la estructura de la tabla destino usando un TTable y añadiendo los correspondientes TFieldDef.

Un campo de Paradox como el descrito antes lo especificaría así:

Código Delphi [-]
with TablaDbase do
begin
  DatabaseName := tu alias;
  TableName := nombre de la tabla;

  with FieldDefs.Add do
  begin
    Name := nombre del campo;
    DataType := ftBCD;
    Precision := 7 ; // ¿9?
    Size := 3;
  end;

  {
    otras definiciones de campo
  }
  end;

  CreateTable;
end;

Ya con la estructura definida puedes usar el BatchMove para hacer la transferencia.

------------------

Nota además que éste tipo de datos (Number en Paradox) no es ni con mucho el único que te va a dar problemas. Money, LongInt, AutoInc, todos esos tendrás que tratarlos según el caso. Creo que el único que no da lata es el Short. En todos los casos tendrás que determinar tú mismo la mejor forma de colocarlos en un NUMBER (BCD) de DBase.

También claro, te causarán problemas los campos Time y TimeStamp; DBase III+ sólo acepta Date (¿en qué estarían pensando los diseñadores de DBase? ) que supongo que tendrás que almacenar como cadenas (campo CHARACTER en DBase) y ni que decir de Graphic, Binary, Bytes, Ole, etc. pues no veo forma de almacenar binarios en DBase III +. Los únicos tipos de datos en DBase son

CHARACTER
NUMBER
DATE
LOGICAL
MEMO

La única forma que veo de guardar datos binarios en DBase III+ es haciendo una codificación de binario a ASCII; no me preguntes cómo porque no sé pero si el correo electrónico lo puede hacer...

Moraleja: ¿Es realmente necesario que exportes a DBase?

------------------

Otra cosa: ¿por qué el requerimiento de usar SQL? Las bases de datos de escritorio como Paradox y DBase no están hechas para SQL. A no ser que sea muy necesario yo prefiero usar TTable en lugar de TQuery ya que el rendimiento es mucho mejor.

// Saludos
Responder Con Cita
  #3  
Antiguo 09-09-2004
Avatar de sitrico
[sitrico] sitrico is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Caracas, Venezuela
Posts: 295
Poder: 22
sitrico Va por buen camino
Gracias Roman, lo que justamente lo que estaba preguntando:¿ como definir por código los campos NUMBER de DBASE ?.

Código Delphi [-]
 with FieldDefs.Add do
  begin
    Name := nombre del campo;
    DataType := ftBCD;
    Precision := 7 ; // ¿9?
    Size := 3;
  end;

En cuanto a la precisión no tengo ningun problema ya que todos mis campos son en realidad currency y los defino (20,2) y algunos enteros (8,0) del resto son Date y String (afortunadamente).

Lo del SQL es pura fiebre, (hace poco q trabajo con el) yo habia medio resuelto el problema creando "Moldes" de las bases de datos de exportación (bases de datos vacias con la estructura correcta) pero ya me pongo a crear mi propia estructura por código

Gracias de nuevo.
__________________
Sitrico
Responder Con Cita
  #4  
Antiguo 08-03-2017
nemesio nemesio is offline
Miembro
 
Registrado: nov 2005
Ubicación: Isla de Margarita, Venezuela
Posts: 377
Poder: 19
nemesio Va por buen camino
Database desktop si permite pasar de Paradox a Dbase

Aunque este es un hilo viejo, difiero de Roman en su afirmación de que ni el Database Desktop permite pasar una tabla Paradox a Dbase. Tienes que abrir un Query, seleccionas la tabla, luego seleccionas todos los campos, una vez seleccionados los campos presionas el ícono "Query Properties", y ahi te aparece una ventana donde escoges en el "Table Type" si quieres guardar el query como paradox o como Dbase, escribes el nombre que le vas a colocar a la tabla , presionas "Aceptar" y listo.
Responder Con Cita
  #5  
Antiguo 08-03-2017
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
Mmm. Hace diez años podría haber abierto el Database Desktop y averiguar de qué estás hablando. Lamentablemente hace muchos, muchos años que ese software ha desaparecido de mi entorno. No obstante, me parece que en ese mensaje me refería a que al importar la estructura de una tabla de paradox a dbase (con la función Borrow), un campo de tipo Numeric se pierde, no que no se pudiera importar .

LineComment Saludos
Responder Con Cita
  #6  
Antiguo 08-03-2017
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.257
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por roman Ver Mensaje
...No obstante, me parece que en ese mensaje me refería a que al importar la estructura de una tabla de paradox a dbase (con la función Borrow), un campo de tipo Numeric se pierde, no que no se pudiera importar .

LineComment Saludos
Pues sí, como dijiste hace 13 años:
Cita:
Los únicos tipos de datos en DBase son

CHARACTER
NUMBER
DATE
LOGICAL
MEMO
Responder Con Cita
  #7  
Antiguo 09-03-2017
Avatar de newtron
[newtron] newtron is offline
Membrillo Premium
 
Registrado: abr 2007
Ubicación: Motril, Granada
Posts: 3.591
Poder: 21
newtron Va camino a la fama
Hola.

Yo ahora estoy en la tarea de pasar mis aplicaciones a la versión Berlin de delphi y uno de los problemas que me he encontrado es la creación y manipulación de tablas .DBF. al final he optado por usar ADO y creo que va bastante bien y no tienes que instalar componentes externos. Te paso la función con la que creo la tabla por si te sirve de ayuda.

Código Delphi [-]
  procedure CreaTablaDBF(Panel: Smallint; CamposTabla: TStringList; CampoTabla: String; Creada: Boolean);
  var
    Path,NombreTabla,Parametros: String;
    i: Smallint;
    ConnStringDBF: String;
  begin
  //
    if not Creada then begin
    //
      if CampoTabla = 'VACIO' then begin
        //Cadena de conexión
        ConnStringDBF := 'Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=%s;';

        //Nombre de la Tabla
        NombreTabla := ExtractFileName(EditFichero.Text);
        Path:=ExtractFilePath(EditFichero.Text);
        Path:=Copy(Path,1,Length(Path)-1);

        if Trim(NombreTabla) = '' then NombreTabla := 'Salida.dbf';

        if UpperCase(Trim(ExtractFileExt(NombreTabla))) = '' then begin
          NombreTabla := NombreTabla + '.DBF';

        end else if UpperCase(Trim(ExtractFileExt(NombreTabla))) <> '.DBF' then begin
          ShowMessage('Si se especifica extension DEBE ser DBF.');
          Exit;

        end;

        if Length(ExtractFileName(NombreTabla)) > 12 then begin
          ShowMessage('Se debe especificar un nombre de fichero de longitud inferior a 8 caracteres.');
          Exit;

        end;

        if not FileExists(ExtractFilePath(EditFichero.Text)+NombreTabla) then begin
          ADOConnDBF := TADOConnection.Create(nil);
          ADOConnDBF.LoginPrompt := False;
          ADOConnDBF.ConnectionString := Format(ConnStringDBF, [Path]);

          ADOCommand := TADOCommand.Create(nil);
          ADOCommand.Connection := ADOConnDBF;
          //Creamos la Tabla de salida
          Parametros:= 'Create Table ' + NombreTabla + ' (';
          for i:=Low(ImpresoAnverso.SeccionPaneles.Panel[Panel].Elemento) to High(ImpresoAnverso.SeccionPaneles.Panel[Panel].Elemento) do begin
            case ImpresoAnverso.SeccionPaneles.Panel[Panel].Elemento[i].TipoCampo of
            //
              teCadena:  Parametros:=Parametros+'CAMPO_'+IntToStr(i)+' CHAR('+IntToSTr(ImpresoAnverso.SeccionPaneles.Panel[Panel].Elemento[i].Longitud)+'),';
              teEntero:  Parametros:=Parametros+'CAMPO_'+IntToStr(i)+' INTEGER,';
              teReal:    Parametros:=Parametros+'CAMPO_'+IntToStr(i)+' CURRENCY,';
              teHora:    Parametros:=Parametros+'CAMPO_'+IntToStr(i)+' CHAR(5),';
              teFecha:   Parametros:=Parametros+'CAMPO_'+IntToStr(i)+' DATE,';
              teMoneda:  Parametros:=Parametros+'CAMPO_'+IntToStr(i)+' CURRENCY,';
              teLogico:  Parametros:=Parametros+'CAMPO_'+IntToStr(i)+' CHAR(1),';
              else       Parametros:=Parametros+'CAMPO_'+IntToStr(i)+' CHAR(255),';
            end;
          end; // with TablaDbf do begin
          Parametros:= Copy(Parametros,1,Length(Parametros)-1)+')';
          ADOCommand.CommandText := Parametros;
          ADOCommand.Execute;
          if ExtractFileName(EditFichero.Text) = '' then begin
          //
            NombreTabla := 'Salida.dbf';
          end else begin
          //
            if UpperCase(Trim(ExtractFileExt(EditFichero.Text))) = '' then begin
              NombreTabla := ExtractFileName(EditFichero.Text) + '.DBF';
            end else begin
              NombreTabla := ExtractFileName(EditFichero.Text);
            end;
          //
          end;
          NombreTabla := ExtractFilePath(EditFichero.Text) + NombreTabla;
          ADOTable:=TADOTable.Create(nil);
          ADOTable.Connection := ADOConnDBF;
          ADOTable.TableName := ExtractFileName(EditFichero.Text);
          ADOTable.Open;
          //
        end; //if FileExist
      //
      end; //if CampoTabla = 'VACIO'
    //
    end else begin
    //
      Try
      //
        ADOTable.append;
        try
          for i:=Low(ImpresoAnverso.SeccionPaneles.Panel[Panel].Elemento) to High(ImpresoAnverso.SeccionPaneles.Panel[Panel].Elemento) do begin
//          TablaSalida.FieldByName(ImpresoAnverso.SeccionPaneles.Panel[Panel].Elemento[i].Campo).AsString := CamposTabla[i];
            ADOTable.FieldByName('CAMPO_' + IntToStr(i)).AsString := CamposTabla[i];
          end; //for
//        TablaSalida.Post;
        finally
          ADOTable.Post;
        end;
      finally
      //
        CamposTabla.Clear;
      end;

    end; //if not Creada

  end;

Saludos
__________________
Be water my friend.
Responder Con Cita
Respuesta



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 01:45:28.


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