Jump to content
Fivewin Brasil

GRAVAÇÃO REMOTO VIA MYSQL


JUDSON

Recommended Posts

Amigos como falei antes estou migrando para mysql ( sqllib ), usando comando dbase ( use , replace ,... ) devido ao tempo para conversao, e ja estou gravando numa base que coloquei na UOL., gostaria que os amigos dessem uma opinião nessa rotina que envia de uma base local para uma remota , achei lento não sei se é a velocidade da net ou existe uma forma melhor de fazer esta rotina, a base so tem 100 registros , com três campos ta levando 3 minutos , imagine com uma tabela de movimento de estoque :

function enviando_baseremota ()
****************************
// DADOS DA BASE LOCAL EM MYSQL
nFile:="Tabela de Grupos..." ; oFile:refresh()
dbselectarea("grup") ; dbgotop()
do while !eof()
nPercent++
wcdgr := grup->cdgr
wdescr:= grup->descr
wpcom := grup->pcom
// Inclui Contato na Base de Dados REMOTA
lresult := SQLSETCONNECTION( ConectaBaseremota )
// Pesquisa Código do Grupo na base remota
cSql := "select cdgr from siigrup where cdgr = "+Any2Sql( wcdgr )
aGrupos := SqlArray( cSql )
If ( SQL_ErrorNO() > 0 )
MsgInfo( "Informe Esta Mensagem Ao Suporte : "+CRLF+SQLErrorMsg(), "Atenção." )
Return( .F. )
Endif
If len( aGrupos ) = 0 // QUANDO NAO ACHA A CHAVE PRIMARIA
cSql := "insert into siigrup set"
else
cSql := "update siigrup set" // QUANDO ENCONTRA A CHAVE PRIMARIA
endif
cSql += " cdgr = "+Any2Sql( wcdgr )
cSql += ", descr = "+Any2Sql( wdescr )
cSql += ", pcom = "+Any2Sql( wpcom )
If len( aGrupos ) > 0
cSql += " where cdgr = "+Any2Sql( wcdgr )
Endif
// Realiza Transação
Begin Transaction
SQL Execute cSql
If ( SQL_ErrorNO() > 0 )
SQLRollBack()
End Transaction
MsgInfo( "Informe Esta Mensagem Ao Suporte : "+CRLF+SQLErrorMsg(), "Atenção." )
Return( NIL )
Endif
End Transaction
ometer:set(npercent)
lresult := SQLSETCONNECTION( ConectaGSERVER1 )
dbselectarea("grup") ; dbskip()
enddo
// lresult := SQLSETCONNECTION( ConectaBaseremota )
// SQLCOMMIT()
lresult := SQLSETCONNECTION( ConectaGSERVER1 )
msgalert("Atualização remota realizada com sucesso.","Atenção")
Return( NIL )

O tempo de gravação é o mesmo quando desligo o SET SESSION AUTOCOMMIT=0 e uso o SQLCOMMIT

dessa forma esta certa ou pode ser melhor esta rotina ?

Link to comment
Share on other sites

Judson eu faria diferente, primeiro para pegar os dados de origem eu faria um select e depois usaria um USE SQL ou SqlArray, e faria toda a atualização dentro de uma única transação, pois no seu código voce abre e fecha uma transação a cada registro. Não sou nenhum expert em sql, mas pode ficar mais rápido.

O exemplo de código não é o ideal eu atualmente crio uma classe para fazer algo assim, mas é apenas para dar uma idéia e principalmente eu usaria SqlArray, não gosto muito do USE SQL.

  local cSql,var1,var2
  
  cSql := "SELECT campo1,"     +;
                  "campo2"     +;
			 " FROM tabela"       +;
	       " WHERE ... " +;
	       " ORDER BY campo1 ;"
  USE SQL (cSql) ALIAS tabela NEW
  
 Begin Transaction //-> inicia a transação
 WHILE !tabela->(Eof()) 
   var1 := tabela->campo1
   var2 := tabela->campo2
  
   if !Inserir(var1,var2)
      //-> se der algum erro voce faz rollback
   endif
   tabela->(DbSkip() ) 
 END	 
  
 tabela->(DbCloseArea() )
 End Transaction //-> fecha a transação
 
 
 
 
 Function Inserir(var1,var2)
  //- aqui faria o insert na tabela de destino
 return(.t.)
Link to comment
Share on other sites

Olá,

Deve-se levar em conta que o fato do servidor estar remoto influencia na execução, pois o resultado dependerá também da sua velocidade de conexão. Além disto, eu colocaria a abertura de transação no inicio da operação (loop) e apenas um commit ao final.

Outro ponto: eu atualizaria o meter não a cada registro processado, mas sim a cada lote de registros processados.

Link to comment
Share on other sites

JUDSON, dá uma analisada nisso, fiz rapidinho, não testei, mas imagino que esteja 100%

FUNCTION TESTE()
 
LOCAL WX
 
LOCAL cSQL
LOCAL aSQL
 
LOCAL aGrup
 
LOCAL lBreak:=.F.
LOCAL cMsg:=''
 
cSQL:='SELECT CDGR'+;
            ',DESCR'+;
            ',PCOM'+;
      ' FROM GRUP ORDER BY CDGR'
aGrup:=sqlArray(cSQL)
 
IF EMPTY(aGrup)
   MSGALERT('Não há dados a exportar.....','')
   RETURN
ENDIF
 
lresult:=SQLSETCONNECTION( ConectaBaseremota )
 
IF !lresult
   MSGALERT('Não foi possível conectar na base remota.....','')
   RETURN
ENDIF
 
**************
BEGIN SEQUENCE
**************
 
   cSQL:='START TRANSACTION'
   sqlExecute(cSQL)
 
   cMsg:=SQLErrorMSG() ; IF !EMPTY(cMsg) ; BREAK ; ENDIF
 
   FOR WX:=1 TO LEN(aGrup)
      x_CDGR := VAL(aGrup[WX,01])
      x_DESCR:=PADR(aGrup[WX,02],40)
      x_PCOM := VAL(aGrup[WX,03])
 
      cSQL:='SELECT CDGR FROM siigrup WHERE CDGR = '+ANY2SQL(x_CDGR)
      aSQL:=sqlArray(cSQL)
 
      cMsg:=SQLErrorMSG() ; IF !EMPTY(cMsg) ; BREAK ; ENDIF
 
      IF EMPTY(aSQL)
         cSQL:='INSERT INTO siigrup (CDGR,DESCR,PCOM) VALUES'
               '(' + ANY2SQL(x_CDGR ) +; //CDGR
               ',' + ANY2SQL(x_DESCR) +; //DESCR
               ',' + ANY2SQL(x_PCOM ) +; //PCOM
               ')'
         sqlExecute(cSQL)
 
         cMsg:=SQLErrorMSG() ; IF !EMPTY(cMsg) ; BREAK ; ENDIF
      ELSE
         cSQL:='UPDATE siigrup SET DESCR = '+ANY2SQL(x_DESCR)+;
                                 ',PCOM  = '+ANY2SQL(x_PCOM )+;
               ' WHERE CDGR = '+ANY2SQL(x_CDGR)
         sqlExecute(cSQL)
 
         cMsg:=SQLErrorMSG() ; IF !EMPTY(cMsg) ; BREAK ; ENDIF
      ENDIF
   NEXT
*******
RECOVER
*******
   cSQL:='ROLLBACK'
   sqlExecute(cSQL)
 
   lBreak:=.T.
************
END SEQUENCE
************
 
IF lBreak
   MSGALERT('Informe a msg ao suporte...'+cMsg,'')
   RETURN
ENDIF
 
cSQL:='COMMIT'
sqlExecute(cSQL)
 
MSGINFO('SUCESSO','')
 
RETURN
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...