Página 1 de 2

Problema com ADO

Enviado: 17 Mai 2021 04:29
por JoséQuintas
É um problema esquisito.
TODOS os terminais acessam como RemoteAPP.
Um único terminal está gerando mensagem de erro, em manifesto, quando está incluindo, e ainda não tem nenhuma nota nele.
No manifesto, é o manifesto e o browse dos documentos, o erro é na lista vazia.
Pedidos com produtos segue o mesmo esquema, mas em pedidos tudo funciona normal.

A rotina é sempre a mesma, então, por enquanto sem idéia.
A única exceção, que ainda não confirmei, é que quando o RemoteAPP é externo à rede, o acesso aos poucos DBFs é por hbnetio.

Problema com ADO

Enviado: 17 Mai 2021 11:18
por JoséQuintas
Não faz sentido porque é somente em remoto DE FORA da empresa, interno não acontece.
Em todo caso, vou alterar isto.

Código: Selecionar todos

   METHOD MoveFirst()                  INLINE iif( ::Rs == Nil, Nil, ::Rs:MoveFirst() )
   METHOD MoveLast()                   INLINE iif( ::Rs == Nil, Nil, ::Rs:MoveLast() )
   METHOD MoveNext()                   INLINE iif( ::Rs == Nil, Nil, ::Rs:MoveNext() )
   METHOD MovePrevious()               INLINE iif( ::Rs == Nil, Nil, ::Rs:MovePrevious() )
   METHOD Move( nValue, ... )          INLINE iif( ::Rs == Nil, Nil, ::Rs:Move( nValue, ... ) ) // 0, 1=begin, 2=end
   METHOD RecordCount()                INLINE iif( ::Rs == Nil, 0, ::Rs:RecordCount() )
pra isto:

Código: Selecionar todos

   METHOD MoveFirst()                  INLINE iif( ::RecordCount() == 0, Nil, ::Rs:MoveFirst() )
   METHOD MoveLast()                   INLINE iif( ::RecordCount() == 0, Nil, ::Rs:MoveLast() )
   METHOD MoveNext()                   INLINE iif( ::RecordCount() == 0, Nil, ::Rs:MoveNext() )
   METHOD MovePrevious()               INLINE iif( ::RecordCount() == 0, Nil, ::Rs:MovePrevious() )
   METHOD Move( nValue, ... )          INLINE iif( ::RecordCount() == 0, Nil, ::Rs:Move( nValue, ... ) ) // 0, 1=begin, 2=end
   METHOD RecordCount()                INLINE iif( ::Rs == Nil, 0, ::Rs:RecordCount() )
Estou me baseando na mensagem de erro.
Uso isso no browse, e já uso o browse em ADO já tem mais de um ano.
Mas é a única possibilidade que vejo.

Ao contrário de DBF, GOTOP, GOBOTTOM, etc. dá erro caso esteja vazio, porque não é possível fazer a operação.
Faz sentido a alteração, só não faz sentido só acontecer em remoto externo.

É uma situação intessante.
Vai saber se não pode acontecer algo parecido no SQLMIX e/ou outros RDDs do Harbour...
Um ano de uso, e agora aparecer isso...

Agora é aguardar se vai resolver.

Problema com ADO

Enviado: 17 Mai 2021 11:23
por JoséQuintas
Nos pedidos, pra mostrar os produtos, é exatamente igual.
Se ficar resolvido em manifestos, aí não vai fazer sentido estar funcionando em pedidos kkkk

Não se faz mais informática como antigamente....
Sempre foi 0 e 1, sim ou não, mas agora tem também o talvez... kkk

Problema com ADO

Enviado: 17 Mai 2021 15:23
por alxsts
Olá!
JoséQuintas escreveu:Estou me baseando na mensagem de erro
Mas qual é a mensagem? Que operação está sendo feita no momento do erro?
JoséQuintas escreveu:Em todo caso, vou alterar isto. 1    METHOD MoveFirst()                  INLINE iif( ::Rs == Nil, Nil, ::Rs:MoveFirst() )
Acho que não vai resolver. Meu palpite é que o recordset está fechado. Assim, qualquer operação envolvendo ele vai dar erro. Tente:

Código: Selecionar todos

// #include ado.ch
METHOD MoveFirst() INLINE iif( ::Rs != Nil .And. ::Rs:state == adStateOpen, ::Rs:MoveFirst(), Nil )

Problema com ADO

Enviado: 17 Mai 2021 17:48
por JoséQuintas
Error WINOLE/1007 BOF ou EOF são verdadeiros, ou o registro atual foi excluído. A operação solicitada pelo aplicativo requer um registro atual. (0x800A0BCD): ADODB.Recordset;(DOS Error -2147352567)
Called from WIN_OLEAUTO:MOVEFIRST(0)
Called from (b)ADOCLASS(130)
Called from ADOCLASS:MOVEFIRST(0)
Called from (b)BROWSEADORC(25)
Called from TBROWSE:GOTOP(1195)
Called from BROWSEADORC(102)
Called from JPMDFCABCLASS:TELADADOS(264)
Called from JPMDFCABCLASS:EXECUTE(426)
Called from PJPMDFCAB(21)
Called from DO(0)
Called from DOPRG(144)
Called from (b)RUNMODULE(109)
A mensagem de erro é a mesma de quando tem zero registros.

Lenbrando:
Só acontece numa máquina remota fora da empresa, nas máquinas remotas dentro da empresa sempre ficou resolvido com o teste de Nil.
Pra complicar mais: só numa tela, em outra igual não.
E pra complicar mais ainda: a rotina de browse é ÚNICA para o aplicativo INTEIRO.

É algo fora do normal, é como uma solução para o que já funciona, mas que em determinada situação não está funcionando.

Uma coisa é certa: se o erro é de recordset, significa que o recordset existe, e não é Nil, como costuma ser.

Problema com ADO

Enviado: 17 Mai 2021 17:52
por JoséQuintas

Código: Selecionar todos

         WITH OBJECT cnSQLBrowse
            :cSQL := "SELECT JPMDFDET.*, JPCADASTRO.CDNOME" + ;
               " FROM JPMDFDET" + ;
               " LEFT JOIN JPCADASTRO ON JPCADASTRO.IDCADASTRO = JPMDFDET.MDCLIENTE" + ;
               " WHERE MDMDFNUM = " + NumberSQL( nIdManifesto )
            :Execute()
            KEYBOARD Chr( K_ESC )
            BrowseADORC( nRowTBrowse, 0, MaxRow() - 3, MaxCol(), @cnSQLBrowse, oTBrowse )
            :CloseRecordset()
         ENDWITH

Problema com ADO

Enviado: 17 Mai 2021 17:55
por JoséQuintas
Por causa desse erro até acrescentei pra limpar o RS no Execute, mas não resolveu.

Código: Selecionar todos

METHOD Execute( cSQL, lError ) CLASS ADOClass

   ::Rs := NIL
   ::Rs := ::ExecuteCmd( cSQL, lError )

   RETURN NIL
Mas pensando bem... ele tá errado..

Problema com ADO

Enviado: 17 Mai 2021 17:59
por JoséQuintas
Não, ele está certo, porque no ExecuteCmd() tem isto:

Código: Selecionar todos

   cSQL := iif( cSQL == Nil, ::cSQL, cSQL ) // não pode usar hb_Default
é que geralmente uso assim:

Código: Selecionar todos

cnSQL:cSQL := "xxxx"
cnSQL:Execute()
Por um momento achei que faltava a linha que está no ExecuteCmd().
Mas não precisa, porque ao repassar já está fazendo a checagem.

Problema com ADO

Enviado: 17 Mai 2021 18:08
por JoséQuintas
Voltando à mensagem de erro:
Error WINOLE/1007 BOF ou EOF são verdadeiros, ou o registro atual foi excluído.
A operação solicitada pelo aplicativo requer um registro atual. (0x800A0BCD):
ADODB.Recordset;(DOS Error -2147352567)
Apenas dividi pra destacar a última parte.
Mostra erro no ADODB.Recordset.

Isso significa que RS contém um recordset, coisa que normalmente não tem pra conteúdo vazio.
O retorno normal tem sido Nil.

Acho que a mudança que fiz vai resolver, porque testa quantidade de registros, sendo que a quantidade também faz a checagem de Nil.
Vale existindo ou não retorno.
Esperar o teste prático.

Problema com ADO

Enviado: 17 Mai 2021 19:32
por JoséQuintas
O erro apareceu UM ANO depois de estar em uso, e só numa determinada situação.

TODOS os manifestos são feitos dentro da empresa, e por remoteAPP.
Mas, de vez em quando precisa fazer num domingo, por exemplo, e é onde usa remoto externo, também por RemoteAPP.
E pra chegar no manifesto, primeiro tem os pedidos/notas fiscais, que usam mesmo esquema.

O problema é o ADO em remoteApp? mas porque só externo?
O problema é o ADO com hbnetio em remoto? mas porque só em manifestos?
Pois é... mais um acontecimento pra lista de mistérios Microsoft...

Falta testar se a alteração vai resolver.

Lembrei do ADS, onde tem configuração separada pra quando é remoto....

Problema com ADO

Enviado: 18 Mai 2021 02:30
por alxsts
Olá!

Talvez testar assim seja melhor:

Código: Selecionar todos

METHOD MoveFirst()         INLINE If( ::Rs != Nil .And. ( ! ::Rs:bof() .And. ! ::eof() ), ::Rs:MoveFirst(), NIL )
METHOD MoveLast()          INLINE If( ::Rs != Nil .And. ( ! ::Rs:bof() .And. ! ::eof() ), ::Rs:MoveLast(), NIL )
METHOD MoveNext()          INLINE If( ::Rs != Nil .And. ( ! ::Rs:bof() .And. ! ::eof() ), ::Rs:MoveNext(), NIL )
METHOD MovePrevious()      INLINE If( ::Rs != Nil .And. ( ! ::Rs:bof() .And. ! ::eof() ), ::Rs:MovePrevious(), NIL )
METHOD Move( nValue, ... ) INLINE If( ::Rs != Nil .And. ( ! ::Rs:bof() .And. ! ::eof() ), ::Rs:Move( nValue, ... ) ) // 0, 1=begin, 2=end
METHOD RecordCount()       INLINE If( ::Rs != Nil .And. ( ! ::Rs:bof() .And. ! ::eof() ), ::Rs:RecordCount(), 0 )
Será que, pelo fato de ser remoto, a consulta não está demorando além do normal? Aumentou o timeout da conexão para execução de comandos?

Código: Selecionar todos

conn:CommandTimeout := 300   // 300 segundos, 5 minutos (o default é 30 segundos)
O código abaixo mostra como aguardar a execução de um processo mais longo. Talvez te interesse:

Código: Selecionar todos

      cCnString := "DRIVER={MariaDB ODBC 3.1 Driver};TCPIP=1;SERVER=localhost;Database=test;UID=root;PWD=pwd;PORT=3306"

      oCn := win_OleCreateObject("ADODB.Connection")

      oCn:ConnectionString := cCnString
      oCn:CursorLocation := adUseClient
      oCn:Mode := adModeReadWrite

      oCn:open()
      
      oRs := oCn:Execute("spContador", ,adAsyncExecute)

      // The State property can have a combination of values. 
      // If a statement is executing, this property will have a 
      // combined value of adStateOpen and adStateExecuting.

      While oCn:State == adStateOpen + adStateExecuting   
         hb_idleSleep(3) 
      Enddo

      IF oRs != NIL .And. oRs:state = adStateOpen
         oTbr := TBrowse():new( 02, 3, MaxRow() - 3, MaxCol() - 3 )
...
Stored Procedure de teste:

Código: Selecionar todos

CREATE DEFINER=`root`@`localhost` PROCEDURE `spContador`()
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
   
   DECLARE n  INT(6) Default 0;

   WHILE n < 1000000
   DO
     SET n = n+1;
   END WHILE;
   
   SELECT * from tbAcoes;
   
END

Código: Selecionar todos

????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
?            codigo        marca        hrvisto        compvenda        dtcotacao        hrcotacao                 ?
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
?                      1 ?            ?        98989 ?              0 ? 28/04/2021     ? 19:34                     ?
?                      2 ?            ?        99949 ?              0 ? 28/04/2021     ? 19:32                     ?
?                      3 ? V          ?        99799 ?              1 ? 28/04/2021     ? 19:31                     ?
?                      4 ?            ?        99849 ?              0 ? 28/04/2021     ? 19:30                     ?
?                      5 ? A          ?        99699 ?              1 ? 28/04/2021     ? 19:29                     ?
?                      6 ?            ?        99749 ?              0 ? 28/04/2021     ? 19:28                     ?
?                      7 ? A          ?        99599 ?              1 ? 28/04/2021     ? 19:27                     ?
?                      8 ?            ?        99649 ?              0 ? 28/04/2021     ? 19:26                     ?
?                      9 ? V          ?        99499 ?              1 ? 28/04/2021     ? 19:25                     ?
?                     10 ?            ?        99549 ?              0 ? 28/04/2021     ? 19:24                     ?
?                     11 ? A          ?        99399 ?              1 ? 28/04/2021     ? 19:23                     ?
?                     12 ?            ?        99449 ?              0 ? 28/04/2021     ? 19:22                     ?

Problema com ADO

Enviado: 24 Mai 2021 15:37
por JoséQuintas
Fiz do jeito que mencionei, mas por enquanto gerei outro problema.

Trocar filtro quando um filtro já existe

Como já existe um filtro, acaba acusando eof() que é o resultado do filtro anterior.

Exagerei no uso de RecordCount(). No filtro basta testar se é Nil.

Problema com ADO

Enviado: 26 Mai 2021 21:45
por JoséQuintas
Só hoje pude confirmar.
Problema resolvido.

Conclusão:

Na maioria das vezes, um retorno sem registro retorna Nil, mas eventualmente retorna 0 registros.
O problema ocorreu após mais de um ano de uso contínuo, e só numa determinada situação, em um determinado terminal.

Talvez possa acontecer com SQLMIX ou outros conectores.

Basicamente isto:

Código: Selecionar todos

Rs := cn:Execute( "SELECT ..." )
IF Rs == Nil 
   ? "Não tem retorno"
ENDIF
se altera pra isto:

Código: Selecionar todos

Rs := cn:Execute( "SELECT ..." )
IF Rs == Nil .OR. Rs:RecordCount() == 0
   ? "Não tem retorno"
ENDIF
Lógico, na minha classe, alterados todos os métodos com esse tipo de checagem.

Pelo menos agora não vai dar erro de jeito nenhum.

Problema com ADO

Enviado: 27 Mai 2021 09:13
por Fernando queiroz
a algum tempo eu já vinha relatando esse problema, já tinha tentado varias coisas, vou tentar mais esta.
no meu caso tinha notado que estava retornando algo que nao dava para detectar, talvez NIL , pois o erro acontecia esporadicamente, não tendo como testar por repetição

tinha momento que ocorria e em seguida fazendo o mesmo procedimento não ocorria.

Problema com ADO

Enviado: 27 Mai 2021 09:37
por Fernando queiroz
outra coisa que tenho notado tambem é que se demorar o retorno de alguma coisa ao banco de dados o próximo comando na sequencia não será executado

ex:

oQuery := CONECCOESCLASS():ExecuteSQL(::oServer, cQuery) -->> se sair por timeout a próxima linha de comandos não será executada
if oQuery != NIL .or. oQuery:RecordCount() != 0

ja me aconteceu varias vezes, nao entendo porque, alguem tem ideia sobre o porque????

outro ex:

N CLICK {||oDlg:oPhantom:SETFOCUS(), IF( hwg_MsgYesNo("DESEJA encerrar Transferência ?","Finalizar Rotina"), { ::TRANSFERENCIA_FINALIZA( VAL(SUBSTR(aList[::FINALIDADE],1,2)) ), oDlg:Close() }, oDlg:oBrowse1:REFRESH() ) }

a rotina TRANSFERENCIA_FINALIZA saiu por timeout mas sem o retorno do banco de dados , mas os comando SQL no banco foram executados, mas em seguida o oDlg:Close() nao foi