Clipper On Line • Ver Tópico - Tutorial de ADO

Tutorial de ADO

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

 

Tutorial de ADO

Mensagempor JoséQuintas » 23 Ago 2017 06:02

Só pro texto ficar num lugar mais adequado:

ADO é como se fosse uma RDD, pra ler qualquer base de dados.
Neste caso o "driver" de Excel permite trabalhar com a planilha como se fosse banco de dados.
No ADO tem também conector pra TXT, XML, etc.
Trabalha-se como qualquer banco de dados, igual pra todos.

No caso do Harbour, as RDDs permitem trabalhar "estilo DBF".
No caso do ADO, não sei dizer se é "estilo Access" ou estilo ADO mesmo.
Ele tem suas propriedades e métodos, do mesmo jeito que o Harbour tem pra DBF.

Recordset é a tabela, como se fosse um arquivo DBF.
Tem-se as funções :Eof(), :MoveNext(), :MovePrevicous(), :RecordCount(), etc.

Cada registro, igual o DBF tem seus campos, acessados por Fields()
:Name, :Value, etc.

Gerar o recordset (temporário) com o resultado de uma consulta
Rs := Conexao:Execute( "SELECT * FROM tabela" )


Trabalhar com recordset
? "total de registros:" + Str( Rs:RecourdCount() )
? "Total de campos:" + Str( Rs:Fields:Count() )
DO WHILE ! Rs:Eof()
   ? Rs:Fields(0):Value // o primeiro item é 0 e não 1
   Rs:MoveNext()
ENDDO


Acessar os campos
? Rs:Fields(1):Value
? rs:Fields( "CODIGO" ):Value
rs:Fields( "CODIGO" ) = valor
rs:Edit()
rs:Update()
rs:Append()


É um acesso universal a qualquer base de dados, praticamente um RDD universal.
Não é muito divulgado no Harbour porque é formato proprietário da Microsoft, e mais específico pra Windows.

Simplificando: temos acesso a qualquer base de dados no Windows... mas é Windows. Até Excel está incluso nisso.
O uso é livre, mas não é Open Source, e talvez não tenha igual em Linux.

Talvez até isso tenha sido considerado como "A Microsoft querendo dominar o mercado"....rs
Enquanto isso permite usar qualquer base de dados GRÁTIS, no Harbour indicam produtos comerciais PAGOS pra ficar igual DBF.

ADO é só a parte intermediária, o ODBC é que vai dar o tratamento final, uma espécie de driver. Sempre vai depender de existir um "driver" para o banco de dados, quanto mais compatível com ADO melhor. Por isso nem toda base de dados funciona a plena carga no ADO, porque não fizeram "tão compatível". Alguns, como os primeiros ODBC pra dBASE, eram somente pra leitura.
Daria até pra criar um aplicativo somente com ADO e nada mais, usando o formato do ADO pras bases de dados.
Não foi feito pra isso, mas é possível usar, substituindo DBFs por ADO.

Esta parte já seria pra fazer atualizações no recordset, ou até na base de dados, no estilo do ADO.
Como eu disse antes, tudo depende do ODBC ("driver") ter sido criado totalmente compatível com ADO, o que é difícil.
Mas comando SQL sempre funciona.

rs:Fields( "CODIGO" ) = valor
rs:Edit()
rs:Update()
rs:Append()
rs:Find()


Esta última parte acabei NUNCA usando.
Mais informações, no site Microsoft, pra lista completa de métodos e propriedades, com muita coisa que NUNCA iremos usar.

Faltou aqui da conexão, ou do arquivo físico de ADO:
Cn := win_OleCreateObject( "ADODB.Connection" )
Rs := win_OleCreateObject( "ADODB.Recordset" )
:Open()
:Close()
:ConnectionString
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Tutorial de ADO

Mensagempor asimoes » 08 Mar 2018 12:44

Voltado ao assunto:

Tenho uma consulta que retorna 8000 linhas, acontece o seguinte toda vez que o método execute é feito vem a ampulheta do windows de demora e a famosa mensagem do windows "Não está respondendo" Isso é muito chato ao meu ver, porque da impressão para o usuário que o sistema está falhando, no final o browser é carregado, existe alguma forma de resolver isso ? Notem que até os componentes da tela somem!

2018-03-08 12_40_41-.png
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Tutorial de ADO

Mensagempor JoséQuintas » 08 Mar 2018 14:06

Talvez fazer o processo numa janela invisível.
Sem janela não vai ter esse efeito.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Tutorial de ADO

Mensagempor sygecom » 08 Mar 2018 15:00

asimoes,
Não seria o caso de colocar uma paginação, pra ir trazendo de pouco em pouco os registros ? Tipo 500 por pagina...
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
leonardodemachado@hotmail.com

Faça você também sua doação esse fórum é uma lenda viva: http://www.pctoledo.com.br/doacao
Avatar de usuário

sygecom
Usuário Nível 7

Usuário Nível 7
 
Mensagens: 7006
Data de registro: 21 Jul 2006 10:12
Cidade/Estado: Alvorada-RS
Curtiu: 1 vez
Mens.Curtidas: 130 vezes

Tutorial de ADO

Mensagempor asimoes » 08 Mar 2018 21:10

Tentei até por thread mais não funcionou,

O incrível é 8000 registros coisa boba para dbf rs
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Tutorial de ADO

Mensagempor asimoes » 08 Mar 2018 21:41

Pensando uma conta aqui

Para saber o número de linhas da tabela faria antes select count(*) from tabela
8000 / 500 = 16

Teria que montar um vetor com isso
E limitando por rownum >= e <=

SELECT * FROM TABELA WHERE ... FILTROS AND ROWNUM >= Vetor[1] and rownnum <= Vetor[2]

Vai fazer 16 selects

Essa tabela eu alimento um dbf temporário

Vetor
01   0001   0501
02   0502   1002
03   1003   1503
04   1504   2004
05   2005   2505
06   2506   3006
07   3007   3507
08   3508   4008
09   4009   4509
10   4510   5010
11   5011   5511
12   5512   6012
13   6013   6513
14   6514   7014
15   7015   7515
16   7516   8016 esse aqui seria o caso de fixar a conta para 8000



To viajando aqui, não sei se vai ficar legal, rs
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Tutorial de ADO

Mensagempor alxsts » 08 Mar 2018 22:54

Olá

Não seria o caso de melhorar a performance desta consulta? Verifique índices, chaves...

Para paginação, tem o exemplo DICA: PAGINAÇÃO EM CONSULTAS SQL

Seria o caso de colocar em uma procedure e passar os limites por parametro.
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

Tutorial de ADO

Mensagempor JoséQuintas » 09 Mar 2018 09:09

É mesmo, faltou a pergunta principal: de quanta demora estamos falando? quantos segundos?
Precisa mesmo todos os campos? SELECT * FROM...
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Tutorial de ADO

Mensagempor asimoes » 09 Mar 2018 15:50

Pessoal,

Consegui montar a query fazendo paginação, logo mais eu posto aqui, respondendo ao Quintas, +- 40 segundos, depende também da utilização do banco.

Consegui trazer todos os registros sem o incomodo "não está respondendo"
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Tutorial de ADO

Mensagempor asimoes » 09 Mar 2018 19:58

AdoSel1 - função que traz uma linha
Exportando para tabela temporária em memória

Com isso resolvi o problema "não está respondendo" e até ficou mais rápido, antes +- 30 seg agora 6 seg.
   cQuery := "SELECT Count(*) TOTAL FROM EXPEDIENTE.EXPEDIENTE"  
   
   IF AdoSel1( @cRecordSet, @aDados, cQuery, , @cErro ) = 0
      nTotal := aDados[1] // vetor contendo o total de linhas da tabela
      IF nTotal > 500
         aRowNum := {}
         nTotalSelect := nTotal / 1000 // traz 1000 linhas por vez até acabar
         nLinSel := 1         
         FOR I:=1 TO nTotalSelect
            aAdd( aRowNum, {nLinSel, nLinSel += 1000} )
            nLinSel ++
         NEXT
         aRowNum[nTotalSelect, 2] := nTotal
      ENDIF
   ENDIF
   
   
   cQuery := "SELECT *                          "
   cQuery += "FROM ( SELECT topn.*, ROWNUM rnum "
   cQuery += "FROM ( SELECT  E.*                "
   cQuery += "FROM EXPEDIENTE.EXPEDIENTE E      "
   cQuery += "ORDER BY ROWID ) topn             "
   cQuery += "WHERE ROWNUM <= ? )               " // LINHA FINAL
   cQuery += "WHERE rnum  >= ?                  " // LINHA INICIAL   
   
   FOR EACH oElemento IN aRowNum
      aResult := {}
      aChave  := { oElemento[2], oElemento[1] }
      IF AdoSelect( @cRecordSet, @aResult, cQuery, aChave, , @cErro ) = 0
         FOR EACH oElementoQuery IN aResult
            hwg_WriteStatus( ThisForm, 1, 'Aguarde... ' + Hb_NtoS( oElemento:__EnumIndex ) + "/" + Hb_NtoS( Len( aRowNum ) ) )
            ORGAO->( DBSeek( oElementoQuery[04] ) )
            aAdd( aExpediente, { oElementoQuery[05], ;
                                 SubStr( oElementoQuery[03], 5, 3 ) + SubStr( oElementoQuery[03], 1, 4 ), ; 
                                 Win_OemToAnsi( ORGAO->Descricao ), ; // Win_OemToAnsi para exibir caracteres acentuados no browse HwGui
                                 Win_OemToAnsi( oElementoQuery[08] ), ;
                                 Win_OemToAnsi( oElementoQuery[09] ), ;
                                 Win_OemToAnsi( oElementoQuery[10] ), ;
                                 IF(oElementoQuery[12] = '1', 'Sim','Não') } )
            hwg_DoEvents()
         NEXT
      ENDIF   
   NEXT
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Tutorial de ADO

Mensagempor asimoes » 31 Mai 2018 18:34

Quintas,

Como é que eu faço para criar uma query que faça leitura de registros de 1000 em 1000 até o fim da tabela ?
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Tutorial de ADO

Mensagempor JoséQuintas » 02 Jun 2018 00:56

asimoes escreveu:Como é que eu faço para criar uma query que faça leitura de registros de 1000 em 1000 até o fim da tabela ?


Com MySQL é: limit x,y

por exemlo:

limit 1, 1000
limit 1001, 2000
etc
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18010
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Tutorial de ADO

Mensagempor asimoes » 02 Jun 2018 10:45

O exemplo tem 25404 registros, modifiquei o conteúdo de alguns campos por se tratar de dados de clientes, vejam o tempo que leva para ler a tabela.

Anexos
LerDbf.zip
(933.66 KiB) Baixado 120 vezes
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Tutorial de ADO

Mensagempor asimoes » 02 Jun 2018 11:10

Se não quiser usar a variável nRecno pode usar ResultSet:AbsolutePosition

        IF Mod( ResultSet:AbsolutePosition, 1000 ) = 0 .OR. ResultSet:AbsolutePosition = 1
            @ 11,00 SAY "Tempo Lendo     : " + SecToTime( Seconds() - nSeconds )
            @ 12,00 SAY "Total Registros : " + Transform( nTot, "99999999")
            @ 13,00 SAY "Evento          : " + Transform( ResultSet:AbsolutePosition, "99999999")
            @ 13,Col() + 2 SAY Transform( ( ResultSet:AbsolutePosition / nTot ) * 100, "999.99%" )
         ENDIF
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Tutorial de ADO

Mensagempor asimoes » 02 Jun 2018 13:30

O que eu notei é que nos primeiros 1000 registros é rápido +- 10 segundos depois esse tempo vai aumentando até chegar aproximadamente 4 minutos ou mais a cada ciclo de 1000 registros.
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Anterior Próximo



Retornar para Contribuições, Dicas e Tutoriais

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 13 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro