Página 4 de 7

Tutorial de ADO

Enviado: 21 Mar 2016 18:43
por asimoes
Quintas,

Perguntas, subindo dados de um dbf para o mysql, e nesse dbf tem datas vazias ' / / ' como você trataria a carga nestes casos?

Tutorial de ADO

Enviado: 21 Mar 2016 19:14
por asimoes
Quintas,

Como não vejo uma solução, vou usar a forma tradicional, lembrando que com oracle funciona createparameter/bind

Código: Selecionar todos

              FOR EACH oElemento2 IN aTheDBF
                  lLast  := oElemento2:__enumIsLast() 
                  cNomeCampo:=Upper(oElemento2[1])
                  cTheValue := &( oElemento2[1] )
                  DO CASE
                  CASE oElemento2[2] = "N"
                       cQuery += Str(cTheValue)+IF(!lLast, ", ", "")
                  CASE oElemento2[2] = "D"
                       IF Empty(cTheValue)
                          cQuery +='null'+IF(!lLast, ", ", "")
                       ELSE
                          cQuery +="'"+Transform( Dtos( cTheValue ), "@R 9999-99-99" )+"'"+IF(!lLast, ", ", "")  
                       ENDIF
                  CASE oElemento2[2] = "L"
                       cTheValue:="'"+IF(cTheValue, "T", "F")+"'"
                       cQuery +=cTheValue+IF(!lLast, ", ", "")
                  CASE oElemento2[2] = "C"
                       cTheValue:="'"+cTheValue+"'"
                       cQuery += cTheValue+IF(!lLast, ", ", "")
                  CASE oElemento2[2] = "M"
                       cTheValue:=Memoread( oElemento2[1] )
                       //cTheValue:="'"+cTheValue+"'"
                       cQuery += cTheValue+IF(!lLast, ", ", "")
                  ENDCASE
               NEXT

Tutorial de ADO

Enviado: 21 Mar 2016 20:32
por JoséQuintas
Já postei isso: NULL
Segue o que uso.

Simplificando: ValueSql(), ou uma função apropriada pra cada tipo.

Código: Selecionar todos

cSql := "INSERT INTO ARQUIVO ( CODIGO, NOME, ENDERECO ) VALUES ( " + ValueSql( mcodigo ) + ", " + ValueSql( mnome ) + ", " + ValueSql( mendereco ) + ")"
cnMySql:Execute( cSql )

Código: Selecionar todos

FUNCTION StringSql( cString )

   cString := Trim( cString )
   cString := StrTran( cString, [\], [\\] )
   cString := StrTran( cString, ['], [\'] )
   cString := StrTran( cString, Chr(13), "\" + Chr(13) )
   cString := StrTran( cString, Chr(10), "\" + Chr(10) )
   cString := ['] + cString + [']
   RETURN cString


FUNCTION DateSql( dDate )

   LOCAL cString

   cString := StrZero( Year( dDate ), 4 ) + "-" + StrZero( Month( dDate ), 2 ) + "-" + StrZero( Day( dDate ), 2 )
   IF cString == "0000-00-00"
      cString := "NULL"
   ELSE
      cString := StringSql( cString )
   ENDIF
   RETURN cString


FUNCTION NumberSql( xValue )

   xValue := Ltrim( Str( xValue ) )
   IF "." $ xValue
      DO WHILE Right( xValue, 1 ) == "0"
         xValue := Substr( xValue, 1, Len( xValue ) - 1 )
      ENDDO
      IF Right( xValue, 1 ) == "."
         xValue := Substr( xValue, 1, Len( xValue ) - 1 )
      ENDIF
   ENDIF
   RETURN xValue


FUNCTION ValueSql( xValue )

   LOCAL cString

   DO CASE
   CASE ValType( xValue ) == "N"
      cString := NumberSql( xValue )
   CASE ValType( xValue ) == "D"
      cString := DateSql( xValue )
   OTHERWISE
      cString := StringSql( xValue )
   ENDCASE
   RETURN cString

E tenho funções equivalentes para fazer o processo contrário.

Tutorial de ADO

Enviado: 21 Mar 2016 20:34
por asimoes
Quintas,

São tantos posts, desculpe-me, eu até fiz isso na minha rotina, depois que percebi.

Tutorial de ADO

Enviado: 21 Mar 2016 20:35
por JoséQuintas
Na sua função, isto está certo?

Código: Selecionar todos

CASE oElemento2[2] = "M" 
   cTheValue:=Memoread( oElemento2[1] ) 
   //cTheValue:="'"+cTheValue+"'" 
   cQuery += cTheValue+IF(!lLast, ", ", "") 
Não é campo do dbf?

Tutorial de ADO

Enviado: 21 Mar 2016 20:39
por JoséQuintas
Uma funçãozinha que criei que pode ser útil:

Código: Selecionar todos

USE CLIENTES
DO WHILE .NOT. Eof()
   CopyRecordToMySql( "CLIENTES", clientes->Codigo )
   SKIP
ENDDO
CLOSE DATABASES

FUNCTION CopyRecordToMySql( cDatabase, cChaveAcesso )

   LOCAL nCont, xValue, lInsert := .T., oRs, cSql

   IF cChaveAcesso != NIL
      cSql := "SELECT COUNT(*) AS QTD FROM " + cDatabase + " WHERE " + cChaveAcesso
      oRs := AppcnMySqlLocal():Execute( cSql )
      IF oRs:Fields( "QTD" ):Value > 0
         lInsert := .F.
      ENDIF
      oRs:Close()
   ENDIF
   IF lInsert
      cSql := "INSERT INTO " + cDatabase + " ( "
      FOR nCont = 1 TO FCount()
         cSql += FieldName( nCont ) + iif( nCont == FCount(), "", ", " )
      NEXT
      cSql += ") VALUES ( "
   ELSE
      cSql := "UPDATE " + cDatabase + " SET "
   ENDIF
   FOR nCont = 1 TO FCount()
      xValue := FieldGet( nCont )
      IF ValType( xValue ) $ "NDC"
         IF ValType( xValue ) == "C"
            xValue := LimpaErro( xValue )
         ENDIF
         IF lInsert
            cSql += ValueSql( xValue )
         ELSE
            cSql += FieldName( nCont ) + "=" + ValueSql( xValue )
         ENDIF
      ELSE
         MsgExclamation( "Tipo desconhecido pra conversão " + ValType( xValue ) )
         QUIT
      ENDIF
      cSql += iif( nCont == FCount(), "", ", " )
   NEXT
   IF lInsert
      cSql += ")"
   ELSE
      cSql += "WHERE " + cChaveAcesso
   ENDIF
   AppcnMySqlLocal():Execute( cSql )
   RETURN NIL

Tutorial de ADO

Enviado: 21 Mar 2016 20:43
por JoséQuintas
A função LimpaErro() foi a forma que encontrei pra eliminar caracteres inválidos que causavam, ou pareciam causar, erro.
Até Chr(0) apareceu no meio dos dbfs....rs

Código: Selecionar todos

STATIC FUNCTION LimpaErro( 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),  "-" )
   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

Tutorial de ADO

Enviado: 21 Mar 2016 21:18
por asimoes
Quintas,

Na verdade eu aboli o campo memo do dbf, isso nem deveria estar no código.

Tutorial de ADO

Enviado: 22 Mar 2016 11:34
por asimoes
Quintas,

Só para atualizar, já estou usando o novo driver odbc 5.3

cConexao := "DRIVER={MySQL ODBC 5.3 Unicode Driver}"
cConexao += ";port=3306;"
cConexao += ";server=" + AllTrim(cServidor)
cConexao += ";database=" + AllTrim(cBanco)
cConexao += ";uid=" + AllTrim(cUsuario)
cConexao += ";pwd=" + AllTrim(cSenha)

Tutorial de ADO

Enviado: 30 Ago 2016 10:05
por asimoes
Pessoal,

Tem como verificar se uma instrução BeginTrans foi iniciada?

Tutorial de ADO

Enviado: 30 Ago 2016 11:33
por JoséQuintas
Acho que isso tem a ver com banco de dados.
Não entendo qual seria a utilidade disso.

Transação é para que uma determinada operação seja salva somente no final, pra ficar "no controle" de eventuais problemas.
Testar se tem transação em andamento, me parece algo sem controle.

Teria mais sentido verificar se tem processos em andamento.

Tutorial de ADO

Enviado: 30 Ago 2016 15:13
por asimoes
Quintas,

Eu já resolvi em parte, o método BeginTrans() retorna um número referente referente a transação, o meu problema é que no oracle não permite múltiplas transações aninhadas,

Tipo:

Código: Selecionar todos

oConnection:BeginTrans()
   oConnection:Execute("INSERT INTO TABELA VALUES('TESTE')")
   oConnection:BeginTrans()
      oConnection:Execute("INSERT INTO TABELA2 VALUES('TESTE')")
   oConnection:CommitTrans()
oConnection:CommitTrans()

Tutorial de ADO

Enviado: 30 Ago 2016 17:48
por alxsts
Olá!
asimoes escreveu:o meu problema é que no oracle não permite múltiplas transações aninhadas
Na verdade, Oracle permite transações aninhadas, inclusive com savepoints e rollback/commit aninhados. Tanto ODBC como ADO não são compatíveis com este comportamento do SGBD Oracle (leia o artigo How To Implement Nested Transactions with Oracle).

Penso que todo este trabalho deveria ser executado por uma stored procedure que retornasse um status de sucesso ou falha e não pela aplicação em si. Dentro da SP você conseguirá fazer as transações aninhadas e tudo mais que for necessário processar no banco de dados...

Tutorial de ADO

Enviado: 12 Dez 2016 20:51
por tonicm
O Viktor Szakats retirou o rddado.
Podemos a continuar a utilizar o mesmo sem problemas?

2016-12-02 20:04 UTC+0100 Viktor Szakats (vszakats users.noreply.github.com)
- extras/gfspell/*
- extras/hbdroid/*
- extras/hbusb/*
- extras/hbvpdf/*
- extras/hbxlsxml/*
- extras/httpsrv/*
- extras/rddado/*
* package/mpkg_win.sh
- remove unfinished, unmaintaned and/or broken packages from the /extras
directory.
You can find the last revision of them archived here:
https://harbour.github.io/archive/gfspell.zip
https://harbour.github.io/archive/hbdroid.zip
https://harbour.github.io/archive/hbusb.zip
https://harbour.github.io/archive/hbvpdf.zip
https://harbour.github.io/archive/hbxlsxml.zip
https://harbour.github.io/archive/httpsrv.zip
https://harbour.github.io/archive/rddado.zip
(Note these contain several maintenance updates compared
to the latest version hosted as part of mainline 3.2 Harbour)
Or as part of the last repository archive that still contained them:
https://github.com/vszakats/harbour-cor ... 170812.zip

Tutorial de ADO

Enviado: 12 Dez 2016 21:12
por JoséQuintas
ADO faz parte do Windows.
O que foi descrito neste tópico é sobre ADO, sem nenhuma LIB.