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?
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.