Italian community of Lazarus and Free Pascal

Programmazione => Databases => Topic aperto da: petrusic - Settembre 24, 2021, 05:28:12 pm

Titolo: [Risolto] Errore ZQuery1.Open per "Nessun Record trovato"
Inserito da: petrusic - Settembre 24, 2021, 05:28:12 pm
Dare il titolo a questa nuova discussione non è stato semplice. Spero tuttavia di riuscire a spiegarmi ora:

Nel programma che sto realizzando accedo ai record di una tabella di DB ("riepmovg") la quale contiene sempre un solo record per ciascuna data di calendario registrata.

A inizio programma, una volta accettata la data di registrazione, devo capire se il record riepilogativo per quella giornata esiste, o meno. Lo faccio richiamando una funzione di lettura, ma riporto le istruzioni per arrivare alla Open del DB, in base alla query preparata:
Codice: [Seleziona]
sql:= 'SELECT DtCoMovg, StaDtMovg FROM riepmovg WHERE DtCoMovg = dataCont ORDER BY DtCoMovg';
//  totRecQry:= contRecDbTbX('riepmovg', sql);
Form1.ZQuery1.SQL.Text := sql;
  try
    Form1.ZQuery1.Open;
    except
    on E: Exception do
      WriteLn('ERRORE nella OPEN del ContabFamdb (sql: "' + sql + '" ' + IntToStr(E.HelpContext) + ': ' + E.Message);
  end;
  totRecQry:= Form1.ZQuery1.RecordCount;
  Form1.ZQuery1.Close;
  Result:= totRecQry;                 
 
Quando, alla Open,  si verifica un Exception (per record insesitenti), l'ERRORE letto nella riga writeLn è:
Citazione
ERRORE nella OPEN del ContabFamdb (sql: "SELECT DtCoMovg, StaDtMovg FROM riepmovg WHERE DtCoMovg = dataCont ORDER BY DtCoMovg" 0: SQL Error: SQL logic error
Naturalmente, per effetto dell'Errore alla open, l'istruzione successiva (ZQuery1.RecordCount) non viene eseguita perchè il programma si arresta addirittura.

Dal messaggio capisco soltanto che si è manifestato un errore logico, ma non capisco che è successo per inesistenza dei record cercati.

Se io eseguo la stessa query dentro l'applicativo DB Browser for SQLite mi viene fornita la seguente risposta:
Citazione
Risultato: 0 righe ritornate in 3ms
Alla riga 1:
SELECT DtCoMovg,StaDtMovg FROM riepmovg WHERE DtCoMovg = 20210924

Quindi DB Browser riesce a capire ed informarmi di non avere trovato record nella ricerca.

Vorrei ottenere una risposta simile da Zeoslib. E' possibile?

Titolo: Re:Errore ZQuery1.Open per "Nessun Record trovato"
Inserito da: DragoRosso - Settembre 24, 2021, 06:21:58 pm
"extended error information"

Citazione
The SQLite driver of Zeos 7.2 now can get extended error information from
SQLite and provide much better error descriptions. In Zeos 8.0 this will
be the default. In Zeos 7.2 we introduced the new parameter ExtendedErrorMessage
to enable the behaviour. Setting this parameter to 1 / Yes / true
will get you the extended error messages. This parameter will not exist in
Zeos 8.0 anymore.

Abilita questo intanto. Il parametro "E" della eccezione (di cui tu usi la proprietà "Message") dovrebbe essere equivalente a una particolare classe di eccezione definita direttamente in ZEOS (tipo EDivbyZero, EMathError, etc ...). Provo a cercare dove ZEOS definisce le eccezioni.

Ciao
Titolo: Re:Errore ZQuery1.Open per "Nessun Record trovato"
Inserito da: DragoRosso - Settembre 24, 2021, 06:48:03 pm
Non ho trovato un elenco specifico su ZEOS, prova a "visualizzare" il codice di errore: inttostr(E.ErroCode), quello dovrebbe essere il codice identificativo dell'eccezione.

Il codice ErrorCode non è sempre settato nelle eccezioni, quindi potrebbe essere che il codice di errore non ti possa aiutare.

Ciao
Titolo: Re:Errore ZQuery1.Open per "Nessun Record trovato"
Inserito da: petrusic - Settembre 27, 2021, 04:24:46 pm
prova a "visualizzare" il codice di errore: inttostr(E.ErroCode), quello dovrebbe essere il codice identificativo dell'eccezione.

Il codice ErrorCode non è sempre settato nelle eccezioni, quindi potrebbe essere che il codice di errore non ti possa aiutare.
Ho provato a modificare il mio codice di accesso al DB, cercando di mettere in pratica il tuo suggerimento:
Codice: [Seleziona]
 Form1.ZQuery1.SQL.Text := sql;
  try
    Form1.ZQuery1.Open;
    except
    on E: Exception do
    begin
      WriteLn('ERRORE nella OPEN del ContabFamdb (sql: "' + sql + '" ' + IntToStr(E.ErroCode) + ': ' + E.Message);
      swOpenErro:= True;
    end;
  end;
Purtroppo il compilatore NON riconosce il parametro ErroCode
Citazione
utilmiedb.pas(38,101) Error: identifier idents no member "ErroCode"

Probabilmente l'identificatore ErroCode fa parte di un pacchetto aggiuntivo in Zeos.
Titolo: Re:Errore ZQuery1.Open per "Nessun Record trovato"
Inserito da: DragoRosso - Settembre 27, 2021, 05:02:51 pm
A parte che dopo l'aperitivo ero un pò fuori io ... eventualmente era ErrorCode  ::)

Prova a verificare questo, anche se sono quasi convinto che l'ExceptionCode non viene inizializzato ....

Codice: [Seleziona]
  try
     //inserisci il tuo codice qui ....
   except on e:exception do
     begin
       if e is EExternal then
         ShowMessage(inttostr((E as EExternal).ExceptionRecord^.ExceptionCode));
     end;
  end;

Con calma verifico se si può ritrovare più dettagliatamente l'errore da SQLite ...

Ciao
Titolo: Re:Errore ZQuery1.Open per "Nessun Record trovato"
Inserito da: petrusic - Settembre 27, 2021, 06:51:25 pm
A parte che dopo l'aperitivo ero un pò fuori io ... eventualmente era ErrorCode  ::)
Non cambia niente, perchè, già in fase di scrittura, dopo avere digitato " IntToStr(E.E", prermendo |CTRL|+|Barra Spazio| si apre la finestra d'aiuto dove compare un solo termine che inizia con "E" (Equals), quindi qualsiasi altro termine non viene riconosciuto.

Ho provato l'ultimo tuo codice di suggerimento:
Codice: [Seleziona]
 try
    Form1.ZQuery1.Open;
    except
    on e: exception do
    begin
      if e is EExternal then
      begin
        ShowMessage(inttostr((E as EExternal).ExceptionRecord^.ExceptionCode));
      end;
    end;                                                     
end;

Anche alla riga [i]ShowMessage[/i] il compilatore  da Errore
[quote]
utilmiedb.pas(62,47) Error: identifier idents no member "ExceptionRecord"[/quote]


Titolo: Re:Errore ZQuery1.Open per "Nessun Record trovato"
Inserito da: DragoRosso - Settembre 27, 2021, 07:03:50 pm
Anche alla riga ShowMessage il compilatore  da Errore
Citazione
utilmiedb.pas(62,47) Error: identifier idents no member "ExceptionRecord"

Mi sono dimenticato di riportare che quel record è definito solo x Win  ....

Rimane solo la verifica di cui al precedente post.

Ciao
Titolo: Re:Errore ZQuery1.Open per "Nessun Record trovato"
Inserito da: petrusic - Settembre 29, 2021, 12:04:42 pm
Nel mio piccolo mondo di esperienza ho fatto una prova, comandando una open che mi producesse una condizione di nessun record trovato, ottenendo così zero record letti:
Codice: [Seleziona]
var
 . . .
tot: Integer = 0;
sql:= 'SELECT DtCoMovg FROM riepmovg WHERE StaDtMovg = "K" ORDER BY DtCoMovg';   // StaDtMovg = "K" (valore impossibile)
  try
    Form1.ZQuery1.Open;
    except
    on E: Exception do
    begin
      WriteLn('ERRORE nella OPEN della tabella "ContabFamdb.riepmovg"   -   ' + IntToStr(E.HelpContext) + ': ' + E.Message);
      swdbOpenErro:= True;
    end;
  end;
  tot:= Form1.ZQuery1.RecordCount;   
 . . .                                             
Ho avviato il programma, ma ... ho incassato due sorprese.
- La prima mi andrebbe bene perchè la Open non ha prodotto errori.
- La seconda invece mi ha lasciato di stucco perchè ho trovato la variabile "tot", dopo l'esecuzione dell'istruzione RecordCount, valorizzata a 9, come se la Open avesse trasferito nel buffer di lettura 9 record.
Pur essendo sicuro dell'inesistenza di record con  StaDtMovg = "K", ho eseguito la select in ambito DBBrowser che, a conferma di quanto ricordo, mi ha fornito
la seguente risposta:
Citazione
Risultato: 0 righe ritornate in 11ms
Alla riga 1:
SELECT DtCoMovg FROM riepmovg WHERE StaDtMovg = "K" ORDER BY DtCoMovg
Titolo: Re:Errore ZQuery1.Open per "Nessun Record trovato"
Inserito da: petrusic - Settembre 29, 2021, 12:35:28 pm
Chiedo scusa per avere postato una risposta inutile.
Nel mio codice manca una riga:
Codice: [Seleziona]
sql:= 'SELECT StaDtMovg FROM riepmovg WHERE StaDtMovg = "K" ORDER BY DtCoMovg';
Form1.ZQuery1.SQL.Text := sql;      // <-- Avevo dimenticato Questa
  try
    Form1.ZQuery1.Open;           
 . . .
 
La open ora funziona sempre, cioè, come prima non produce Errore, ma sono in grado di capire che non c'è alcun record che risponda ai parametri impostati nella Select.

Posso dire che, alla fine, il risultato ottenuto risponde alle mie necessità e posso evitare di comandare la lettura di record inesistenti.
Eseguo una Select in più ed allungo un pochino il programma, ma può andare bene lo stesso.