Empezando con ADO

User avatar
cnavarro
Posts: 5792
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Empezando con ADO

Post by cnavarro »

Quiero expresar mi gratitud a Mr. Rick, y a Antonio por supuesto, por el apoyo inicial que me dieron con este tema.
Gracias por sus explicaciones y su tiempo.

I want to express my gratitude to Mr. Rick, and Antonio of course, for the initial support given to me with this issue.
Thank you for your explanations and your time.
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
User avatar
cnavarro
Posts: 5792
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Empezando con ADO

Post by cnavarro »

Antonio
He abierto otro hilo por si tenemos que seguir comentando algunas cosillas mas, al margen del tema del presente hilo

http://forums.fivetechsupport.com/viewt ... 91#p152429
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
User avatar
cnavarro
Posts: 5792
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Empezando con ADO

Post by cnavarro »

Bueno, continuamos
1.- Ya he podido leer la estructura con "todos" los tipos de campo y presentarla en pantalla, y devuelvo un array con:
{ oCat:Tables( i ):Columns( j ):Name , ; // Nombre de la Tabla
cTipo, ; // Tipo de campo -> Estilo DBF
nLen, ; // Longitud
nDec, ; // Decimales
Upper(cTipoEx), ; // Tipo de Campo -> ADO
nTipo } ) // Nº del Tipo de Campo -> ADO

2.- He creado la tabla a partir de una estructura de un .DBF

Code: Select all

Function StructConect( oConexion, oCat, cTbl )

 Local aCampos      := {}
//Local oRecordSet           // No es necesario

 Local i
 Local j
 Local cTipo    := ""
 Local cTipoEx  := ""
 Local nLen     := 0
 Local nDec     := 0
 Local nTipo    := 0

    if Empty( oCat )
       oCatalog := CreateObject("ADOX.Catalog")
       oCat     := oCatalog
    endif
    oCat:ActiveConnection = oConexion   //"your connection string"

    FOR i = 0 TO oCat:Tables:Count() - 1
        //? oCat:Tables( i ):Type
        if Upper( oCat:Tables( i ):Name ) = Upper( cTbl )

           FOR j = 0 TO oCat:Tables( i ):Columns:Count() - 1
               cTipo    := ""
               cTipoEx  := ""
               nLen     := 0
               nDec     := 0
               nTipo    := oCat:Tables( i ):Columns( j ):Type

               //? oCat:Tables( i ):Columns( j ):Precision
               //? oCat:Tables( i ):Columns( j ):NumericScale
               //? oCat:Tables( i ):Columns( j ):DefinedSize
               //? oCat:Tables( i ):Columns( j ):Type
               Do Case

                  Case nTipo = 0
                       cTipoEx := "Empty"

                  Case nTipo = 2
                       cTipoEx := "SmallInt"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := 0

                  Case nTipo = 3
                       cTipoEx := "Integer"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := 0

                  Case nTipo = 4
                       cTipoEx := "Single"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := 0

                  Case nTipo = 5
                       cTipoEx := "Double"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := 2

                  Case nTipo = 6
                       cTipoEx := "Currency"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := 2

                  Case nTipo = 7
                       cTipoEx := "Date"
                       cTipo   := "D"
                       nLen    := 10
                       nDec    := 0

                  Case nTipo = 8
                       cTipoEx := "BSTR"
                       cTipo   := "C"
                       nLen    := oCat:Tables( i ):Columns( j ):DefinedSize

                  Case nTipo = 9
                       cTipoEx := "IDispatch"

                  Case nTipo = 10
                       cTipoEx := "Error"

                  Case nTipo = 11
                       cTipoEx := "Boolean"
                       cTipo   := "L"
                       nLen    := 1
                       nDec    := 0

                  Case nTipo = 12
                       cTipoEx := "Variant"

                  Case nTipo = 13
                       cTipoEx := "IUnknown"

                  Case nTipo = 14
                       cTipoEx := "Decimal"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := oCat:Tables( i ):Columns( j ):NumericScale

                  Case nTipo = 16
                       cTipoEx := "TinyInt"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := 0

                  Case nTipo = 17
                       cTipoEx := "UnsignedTinyInt"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := 0

                  Case nTipo = 18
                       cTipoEx := "UnsignedSmallInt"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := 0

                  Case nTipo = 19
                       cTipoEx := "UnsignedInt"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := 0

                  Case nTipo = 20
                       cTipoEx := "BigInt"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := 0

                  Case nTipo = 21
                       cTipoEx := "UnsignedBigInt"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := 0

                  Case nTipo = 64
                       cTipoEx := "FileTime"

                  Case nTipo = 72
                       cTipoEx := "GUID"

                  Case nTipo = 128
                       cTipoEx := "Binary"
                       cTipo   := "C"
                       nLen    := oCat:Tables( i ):Columns( j ):DefinedSize

                  Case nTipo = 129
                       cTipoEx := "Char"
                       cTipo   := "C"
                       nLen    := oCat:Tables( i ):Columns( j ):DefinedSize

                  Case nTipo = 130
                       cTipoEx := "WChar"
                       cTipo   := "C"
                       nLen    := oCat:Tables( i ):Columns( j ):DefinedSize

                  Case nTipo = 131
                       cTipoEx := "Numeric"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := oCat:Tables( i ):Columns( j ):NumericScale

                  Case nTipo = 132
                       cTipoEx := "UserDefined"
                       cTipo   := "U"  //Ojo -> Valtype( del campo y luego nDec,
                                       //si es numerico, Precision o DefinedSize
                                       //si es caracter ( ESTUDIAR )
                  Case nTipo = 133
                       cTipoEx := "DBDate"
                       cTipo   := "D"
                       nLen    := 10
                       nDec    := 0

                  Case nTipo = 134
                       cTipoEx := "DBTime"

                  Case nTipo = 135
                       cTipoEx := "DBTimeStamp"
                       cTipo   := "D"
                       nLen    := 10
                       nDec    := 0

                  Case nTipo = 136
                       cTipoEx := "Chapter"

                  Case nTipo = 138
                       cTipoEx := "PropVariant"

                  Case nTipo = 139
                       cTipoEx := "VarNumeric"
                       cTipo   := "N"
                       nLen    := oCat:Tables( i ):Columns( j ):Precision
                       nDec    := oCat:Tables( i ):Columns( j ):NumericScale

                  Case nTipo = 200
                       cTipoEx := "VarChar"
                       cTipo   := "C"
                       nLen    := oCat:Tables( i ):Columns( j ):DefinedSize

                  Case nTipo = 201
                       cTipoEx := "LongVarChar"
                       cTipo   := "C"
                       nLen    := Min( 256, oCat:Tables( i ):Columns( j ):DefinedSize )

                  Case nTipo = 202
                       cTipoEx := "VarWChar"
                       cTipo   := "C"
                       nLen    := oCat:Tables( i ):Columns( j ):DefinedSize

                  Case nTipo = 203
                       cTipoEx := "LongVarWChar"
                       cTipo   := "C"
                       nLen    := oCat:Tables( i ):Columns( j ):DefinedSize

                  Case nTipo = 204
                       cTipoEx := "VarBinary"
                       cTipo   := "C"
                       nLen    := oCat:Tables( i ):Columns( j ):DefinedSize

                  Case nTipo = 205
                       cTipoEx := "LongVarBinary"
                       cTipo   := "C"
                       nLen    := oCat:Tables( i ):Columns( j ):DefinedSize

                  Case nTipo = 8192
                       cTipoEx := "Array"

                  Otherwise
                       cTipoEx := "Undefined"
                       cTipo   := "U"
                       nLen    := 0

               EndCase

               AAdd( aCampos, { oCat:Tables( i ):Columns( j ):Name, cTipo, ;
                                nLen, nDec, Upper(cTipoEx), nTipo } )

           NEXT j

        endif
    NEXT i

Return aCampos

//----------------------------------------------------------------------------//

Function CreaADOTable( oConexion, oCat, cTbl , aStruct )
 Local lSw      := .F.
 Local aCampos      := {}
 Local oRecordSet
 Local oTable
 Local lSigue   := .F.
 Local i
 Local j
 Local cTipo    := ""
 Local cTipoEx  := ""
 Local nLen     := 0
 Local nDec     := 0
 Local nTipo    := 0
 Local cCampo   := ""


DEFAULT cTbl    := ""
DEFAULT aStruct := {}

 if !Empty( oConexion )
    if !Empty( cTbl )
       if !Empty( aStruct )
          lSigue   := .T.
       else
          MsgInfo("ESTRUCTURA de la Tabla Vacía","ATENCION")
       endif
    else
       MsgInfo("No se ha indicado nombre de TABLA","ATENCION")
    endif
 else
   MsgInfo("No hay CONEXION Activa","ATENCION")
 endif

 if lSigue
    if Empty( oCat )
       oCatalog := CreateObject("ADOX.Catalog")
       oCat     := oCatalog
    endif
    oCat:ActiveConnection = oConexion   //"your connection string"
    lSw  := .T.
    if ValType( cTbl ) = "C"
       oTable       :=  CreateObject( "ADOX.Table" )
       oTable:Name  :=  cTbl

       oTable:ParentCatalog := oCat

       For i = 1 to Len( aStruct )
           //AAdd( aCampos, nil )
           cTipo    := ""
           cTipoEx  := ""
           nTipo    := 0
           cCampo   := aStruct[i][1]
           cTipo    := aStruct[i][2]
           nLen     := aStruct[i][3]
           nDec     := aStruct[i][4]
           //aCampos[ i ] :=  CreateObject("ADOX.Column")
           Do Case
              Case cTipo = "N"
                   if aStruct[i][4] = 0
                      cTipoEx   := "Integer"
                      nTipo     := 3
                   else
                      if aStruct[i][4] <= 2
                         cTipoEx   := "Double"
                         nTipo     := 5
                      else
                         cTipoEx   := "Decimal"
                         nTipo     := 14
                      endif
                   endif
              Case cTipo = "C"
                   cTipoEx   := "VarWChar"
                   nTipo     := 202

              Case cTipo = "D"
                   cTipoEx   := "Date"
                   nTipo     := 7

              Case cTipo = "L"
                   cTipoEx   := "Boolean"
                   nTipo     := 11

              Case cTipo = "M"
                   cTipoEx   := "LongVarWChar"
                   nTipo     := 203

           EndCase

           //if cTipo <> "N"
           //   nLen := 0
           //endif

           oTable:Columns:Append(cCampo, nTipo, if(empty(nLen),Nil,nLen))
           //oTable:Columns(cCampo):Attributes  := 64    //MayBeNull

           if cTipo = "N"
              nLen  := oTable:Columns(cCampo):Precision
              nDec  := oTable:Columns(cCampo):NumericScale
           else
              nLen  := oTable:Columns(cCampo):DefinedSize
           endif
           AAdd( aCampos, { cCampo, Upper(cTipoEx), nLen, nDec, nTipo, cTipo } )

       Next i
       oCat:Tables:Append( oTable )

    else
       if ValType( cTbl ) = "A"
       For j = 1 to Len( cTbl )
        aCampos      := {}
        oTable       :=  CreateObject( "ADOX.Table" )
        oTable:Name  :=  cTbl[ j ]

        oTable:ParentCatalog := oCat

        For i = 1 to Len( aStruct[j] )
           //AAdd( aCampos, nil )
           cTipo    := ""
           cTipoEx  := ""
           nTipo    := 0
           cCampo   := aStruct[j][i][1]
           cTipo    := aStruct[j][i][2]
           nLen     := aStruct[j][i][3]
           nDec     := aStruct[j][i][4]
           //aCampos[ i ] :=  CreateObject("ADOX.Column")
           Do Case
              Case cTipo = "N"
                   if aStruct[j][i][4] = 0
                      cTipoEx   := "Integer"
                      nTipo     := 3
                   else
                      if aStruct[j][i][4] <= 2
                         cTipoEx   := "Double"
                         nTipo     := 5
                      else
                         cTipoEx   := "Decimal"
                         nTipo     := 14
                      endif
                   endif
              Case cTipo = "C"
                   cTipoEx   := "VarWChar"
                   nTipo     := 202

              Case cTipo = "D"
                   cTipoEx   := "Date"
                   nTipo     := 7

              Case cTipo = "L"
                   cTipoEx   := "Boolean"
                   nTipo     := 11

              Case cTipo = "M"
                   cTipoEx   := "LongVarWChar"
                   nTipo     := 203

           EndCase

           //if cTipo <> "N"
           //   nLen := 0
           //endif

           oTable:Columns:Append(cCampo, nTipo, if(empty(nLen),Nil,nLen))
           //oTable:Columns(cCampo):Attributes  := 64    //MayBeNull

           if cTipo = "N"
              nLen  := oTable:Columns(cCampo):Precision
              nDec  := oTable:Columns(cCampo):NumericScale
           else
              nLen  := oTable:Columns(cCampo):DefinedSize
           endif
           AAdd( aCampos, { cCampo, Upper(cTipoEx), nLen, nDec, nTipo, cTipo } )

        Next i
        oCat:Tables:Append( oTable )

       Next j
       endif
   endif

   TablasConex( oCon, oCatalog, 0,  )
   oXBrwConex:SetArray( aTablasConex )
   oXBrwConex:Refresh()

 endif

Return lSw

//----------------------------------------------------------------------------//
 
El siguiente paso es analizar los property y attributes de las columnas (campos) pero no lo encuentro, como por ejemplo he visto en un hilo de Otto
Alguien me puede dar un "hilo"?

Code: Select all

 
oCol:Properties("Autoincrement", .T.)

oTable:Columns("CODIGO"):Attributes := ADCOLNULLABLE
 
Image

Image

El siguiente paso sera poder crear la tabla desde el principio
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
User avatar
cnavarro
Posts: 5792
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Empezando con ADO

Post by cnavarro »

Aqui pongo dos funciones
La primera para obtener las tablas de una base de datos (distinta a la que existe en FWH)
Y la segunda para borrar una tabla (no la he encontrado en ADOFUNCS), aunque no recuerdo cuando la implementé en qué (o en quien) me "inspiré" ya que en esos momentos no tenía muchos conocimientos de ADO (ahora no muchos más, pero vamos avanzando)

Code: Select all

#define DB_DBASE     1
#define DB_ACCESS    2
#define DB_MSSQL     3
#define DB_MYSQL     4
#define DB_ORACLE    5
#define DB_SQLITE    6


Function FWADOGetAllBases( oConexion, cPathAc )
Local oRs
Local aTablas   := {}
Local aTmp      := {}
Local nTablas
Local lSw       := .F.
Local x
Local lAccess   := if( FW_RDBMSName( oConexion ) ="MSACCESS", .T., .F. )
DEFAULT cPathAc := HB_CurDrive()+":\"+Curdir()+"\"

if !lAccess
   oRs := TOleAuto():New( "ADODB.Recordset" )

   oRs:CursorType       := 1        // opendkeyset
   oRs:CursorLocation   := 3        // local cache
   oRs:LockType         := 3        // lockoptimistic
   oRs:ActiveConnection := oConexion

   TRY
     oRs:Open( "SHOW DATABASES", oConexion ) // "FROM " + cTableName, oCon )
     lSw   := .T.
   CATCH
     oRs := nil
   END

   if lSw
      nTablas   := oRs:RecordCount
      aTablas   := oRs:GetRows( nTablas )
      //? oRs:Source, FW_RDBMSName( oCon )
   endif
else
  // Devolver Array con todas las bases de Datos .MDB
  //? FW_RDBMSName( oCon )
  aTmp     := Directory( RTrim( cPathAc )+"*.mdb" )
  nTablas  := Len( aTmp )
  For x = 1 to nTablas
      AAdd( aTablas, aTmp[ x ][ 1 ] )
  Next x
endif

Return aTablas

//----------------------------------------------------------------------------//

Function FWAdoDeleteTable( cAdoTable, oCn, nDbms )
   local lOk            := .f.
   local lCnOpened      := .f.

   //DEFAULT oCn := soCn
   DEFAULT nDbms := FW_RDBMSName( oCn )

   if ValType( oCn ) != 'O'
      oCn      := FW_OpenAdoConnection( oCn )
      if oCn == nil
         MsgInfo( "Can not open connection" )
         return .f.
      endif
      lCnOpened   := .t.
   endif
   FW_RDBMSName( oCn )

   DEFAULT cAdoTable := ""
   cAdoTable         := cFileNoExt( cAdoTable )

    if FW_AdoTableExists( cAdoTable, oCn )
      if MsgNoYes( cAdoTable + " Exists. Delete? (Y/N)" )
         if nDbms == DB_ORACLE  // snDbms == DB_ORACLE
            cAdoTable   := FW_QuotedColSQL( cAdoTable )
         endif
         TRY
            oCn:Execute( "DROP TABLE " + cAdoTable )
            lOK   := .t.
         CATCH
            MsgInfo( "Can not drop table " + cAdoTable )
         END
         if nDbms == DB_ORACLE  //snDbms == DB_ORACLE
            TRY
               oCn:Execute( "DROP SEQUENCE " + cAdoTable + "_ID_SEQ" )
            CATCH
            END
         endif
      endif
      if ! lOk
         if lCnOpened
            oCn:Close()
         endif
         return .f.
      endif
    endif

Return lOk

//----------------------------------------------------------------------------//

C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
Post Reply