Não entendi nada.
Opção 1: gerar arquivo texto pra ser usado por outro programa
Opção 2: fazer direto
É só pra dar idéia
Código: Selecionar todos
/*
ZE_SQLFROMDBF - Transfere de DBF pra SQL incluindo ou não
José Quintas
*/
#include "inkey.ch"
#include "dbstruct.ch"
#include "josequintas.ch"
#include "ze_adoclass.ch"
FUNCTION SQLFromDbf()
LOCAL oFiles, nCont, acAchoice := {}, cFileDbf, nOpc := 1, cConfirma := "NAO", GetList := {}
@ 2, 1 SAY "ATENÇÃO"
@ Row() + 1, 1 SAY "Os dados dos DBFs são salvos no SQL."
@ Row() + 1, 1 SAY "Se quiser eliminar dados anteriores do SQL, precisa fazer manualmente"
@ Row() + 1, 1 SAY "Se quiser eliminar dados finais do DBF, precisa fazer manualmente"
oFiles := CnfDbfInd()
FOR nCont = 1 TO Len( oFiles )
AAdd( acAchoice, oFiles[ nCont, 1 ] )
NEXT
DO WHILE .T.
wAchoice( Row() + 1, 5, acAchoice, @nOpc, "Arquivos a transferir" )
IF LastKey() == K_ESC
EXIT
ENDIF
cFileDbf := Upper( oFiles[ nOpc, 1 ] )
Mensagem( "Confirme criar estrutura para " + cFileDbf )
@ Row(), Col() + 2 GET cConfirma PICTURE "@!"
READ
Mensagem()
IF LastKey() == K_ESC .OR. cConfirma != "SIM"
LOOP
ENDIF
CopyDbfToSQL( cFileDbf, .F., .T., .F., cFileDbf )
ENDDO
RETURN Nil
FUNCTION CopyDbfToSQL( cTable, lTransfere, lCria, lZera, cNewTable )
LOCAL oStru
LOCAL cSQL, xValue, nCont, cSQLFix
LOCAL lBegin := .T., cTxt, cKeyName
LOCAL cnGERAL := ADOLocal()
LOCAL nSelect := Select()
IF ! File( cTable + iif( ".DBF" $ Upper( cTable ), "", ".DBF" ) )
RETURN Nil
ENDIF
hb_Default( @lCria, .F. )
hb_Default( @lZera, .F. )
hb_Default( @cNewTable, cTable )
cTable := Upper( cTable )
SELECT 0
USE ( cTable ) ALIAS thisdbf
oStru := dbStruct()
cKeyName := "ID" + iif( Left( cTable, 2 ) $ "JP,HL", Substr( cTable, 3 ), cTable )
USE
cSQL := "CREATE TABLE IF NOT EXISTS " + cNewTable + " ( " + cKeyName + " INT(9) NOT NULL AUTO_INCREMENT, "
FOR nCont = 1 TO Len( oStru )
IF oStru[ nCont, DBS_NAME ] != cKeyName
cSQL += oStru[ nCont, DBS_NAME ] + " "
DO CASE
CASE oStru[ nCont, DBS_TYPE ] == "N"
IF oStru[ nCont, DBS_DEC ] == 0
cSQL += " INT( " + Ltrim( Str( oStru[ nCont, DBS_LEN ] ) ) + " ) DEFAULT 0"
ELSE
cSQL += " DECIMAL( " + Ltrim( Str( oStru[ nCont, DBS_LEN ] ) ) + " , " + Ltrim( Str( oStru[ nCont, DBS_DEC ] ) ) + " ) DEFAULT 0"
ENDIF
CASE oStru[ nCont, DBS_TYPE ] == "C"
IF oStru[ nCont, DBS_LEN ] < 250
cSQL += " VARCHAR( " + Ltrim( Str( oStru[ nCont, DBS_LEN ] ) ) + " ) DEFAULT '' "
ELSE
cSQL += " TEXT"
ENDIF
CASE oStru[ nCont, DBS_TYPE ] == "D"
cSQL += " DATE " // DEFAULT '0000-00-00'"
CASE oStru[ nCont, DBS_TYPE ] == "M"
cSQL += " TEXT "
ENDCASE
cSQL += " , "
ENDIF
NEXT
cSQL += " PRIMARY KEY ( " + cKeyName + " )"
cSQL += " )"
cSQL += ";"
SayScroll( "Salvando no SQL." + cTable )
IF lCria
cnGERAL:ExecuteNoReturn( cSQL )
ENDIF
IF lZera
cnGERAL:ExecuteNoReturn( "TRUNCATE TABLE " + cNewTable )
ENDIF
IF ! lTransfere
SELECT ( nSelect )
RETURN Nil
ENDIF
SELECT 0
USE ( cTable ) ALIAS thisdbf
GrafTempo( "Processando " + cTable )
cSQLFix := "INSERT INTO " + cNewTable + " ( "
FOR nCont = 1 TO FCount()
cSQLFix += FieldName( nCont )
IF nCont != FCount()
cSQLFix += ", "
ENDIF
NEXT
cSQLFix += " ) VALUES "
cTxt := ""
DO WHILE ! Eof()
GrafTempo( RecNo(), LastRec() )
Inkey()
cSQL := "( "
FOR nCont = 1 TO FCount()
xValue := FieldGet( nCont )
DO CASE
CASE ValType( xValue ) == "N"
cSQL += NumberSQL( xValue )
CASE ValType( xValue ) == "D"
cSQL += DateSQL( xValue )
CASE ValType( xValue ) == "C"
xValue := SQLValidString( xValue )
cSQL += StringSQL( xValue )
OTHERWISE
cSQL += "NULL"
ENDCASE
IF nCont != FCount()
cSQL += ","
ENDIF
NEXT
cSQL += " )"
IF Len( cTxt ) == 0
cTxt += cSQLFix
lBegin := .T.
ENDIF
IF ! lBegin
cTxt += ", "
ENDIF
lBegin := .F.
cTxt += cSQL
IF Len( cTxt ) > SQL_CMD_MAXSIZE
cnGERAL:ExecuteNoReturn( cTxt )
cTxt := ""
ENDIF
SKIP
ENDDO
IF Len( cTxt ) != 0
cnGERAL:ExecuteNoReturn( cTxt )
ENDIF
USE
SELECT ( nSelect )
RETURN Nil
FUNCTION CopyRecordToSQL( cDatabase, cChaveAcesso )
LOCAL nCont, lInsert := .T., cnSQL := ADOLocal()
IF cChaveAcesso != Nil
lInsert := ( ADORecCount( cDatabase, cChaveAcesso ) == 0 )
ENDIF
WITH OBJECT cnSQL
:QueryCreate()
FOR nCont = 1 TO FCount()
:QueryAdd( FieldName( nCont ), FieldGet( nCont ) )
NEXT
IF lInsert
:QueryExecuteInsert( cDatabase )
ELSE
:QueryExecuteUpdate( cDatabase, cChaveAcesso )
ENDIF
ENDWITH
RETURN Nil
STATIC FUNCTION SQLValidString( xValue )
xValue := StrTran( xValue, Chr(91), " " )
xValue := StrTran( xValue, Chr(93), " " )
xValue := StrTran( xValue, Chr(167), " " )
xValue := StrTran( xValue, Chr(128), "C" )
xValue := StrTran( xValue, Chr(135), "C" )
xValue := StrTran( xValue, Chr(166), "A" )
xValue := StrTran( xValue, Chr(198), "A" )
xValue := StrTran( xValue, Chr(0), "" )
//xValue := StrTran( xValue, Chr(95), "-" ) // usada em email barra inferior
xValue := StrTran( xValue, Chr(229), "O" )
xValue := StrTran( xValue, Chr(124), " " )
xValue := StrTran( xValue, Chr(141), " " )
xValue := StrTran( xValue, Chr(181), " " )
xValue := StrTran( xValue, Chr(162), " " )
xValue := StrTran( xValue, Chr(224), " " )
xValue := StrTran( xValue, Chr(133), " " )
xValue := StrTran( xValue, Chr(144), "E" )
xValue := StrTran( xValue, Chr(160), " " )
RETURN xValue
Crio tabela com campo autoincrement usando as iniciais da tabela.
Gravo tudo do dbf como está.
Tem otimização, porque gravar de 1 em 1 demora demais.
Nem todo caractere é aceito diretamente no MySQL.
Usei no começo, já faz muito tempo, dentro do aplicativo, pode depender de funções do aplicativo.
Mas é só pra dar uma idéia.
QueryCreate() é algo como aList := {}
QueryAdd() é algo como AAdd( aList, { nome, valor } )
QueryExecutexxx() é o que usa a lista pra criar o comando insert ou update, e já converte o valor conforme o tipo.