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:
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 è:
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:
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?
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:
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
utilmiedb.pas(38,101) Error: identifier idents no member "ErroCode"
Probabilmente l'identificatore ErroCode fa parte di un pacchetto aggiuntivo in Zeos.
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 ....
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
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:
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]
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:
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:
Risultato: 0 righe ritornate in 11ms
Alla riga 1:
SELECT DtCoMovg FROM riepmovg WHERE StaDtMovg = "K" ORDER BY DtCoMovg
Chiedo scusa per avere postato una risposta inutile.
Nel mio codice manca una riga:
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.