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.
Empezando con ADO
Re: Empezando con ADO
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.
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.
Re: Empezando con ADO
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
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.
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.
Re: Empezando con ADO
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
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"?
El siguiente paso sera poder crear la tabla desde el principio
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
//----------------------------------------------------------------------------//
Alguien me puede dar un "hilo"?
Code: Select all
oCol:Properties("Autoincrement", .T.)
oTable:Columns("CODIGO"):Attributes := ADCOLNULLABLE
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.
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.
Re: Empezando con ADO
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)
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.
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.