petrusic:
Ho bisogno di risalire all'ultimo numero progressivo di record di diverse tabelle di DB Sqlite3. Da quando ho cominciato a muovermi in lazarus, affidandomi a Zeoslib, ho difficoltà ad eseguire una open della connessione al DB per eseguire successivamente le Query, Insert, Update, Delete che servono. Infine, comandare una unica CommitUpdates o CancelUpdates alla fine di ciascun ramo logico di operazioni. Zeoslib non permette di eseguire la Open della connessione al DB, ma alla singola Query. L'oggetto ZQuery è l'unico agganciato alla procedura Open. Pertanto il codice che segue funziona solo per la prima tabella. dopo di che, il programma innesca una sorta di ciclo infinito.
--- Codice: --- sql:= 'SELECT movimgg.IdMovvgg AS FROM movimgg ORDER BY IdMovvgg DESC LIMIT 1'; Form1.ZQuery1.SQL.Text:= sql; Form1.ZQuery1.Open; Form1.ZQuery1.First; movimggNumId:= StrToInt(Form1.ZQuery1.FieldByName('IdMovvgg').AsString);
sql:= 'SELECT IdPartGlob FROM partmovv ORDER BY IdPartGlob DESC LIMIT 1'; Form1.ZQuery1.SQL.Text:= sql; Form1.ZQuery1.ExecSQL; Form1.ZQuery1.First; partmovNumId:= StrToInt(Form1.ZQuery1.FieldByName('IdPartGlob').AsString);
sql := 'SELECT IdPrestMom FROM prestmom ORDER BY IdPrestMom DESC LIMIT 1'; Form1.ZQuery1.SQL.Text := sql; Form1.ZQuery1.ExecSQL; Form1.ZQuery1.First; prestmomNumId:= StrToInt(Form1.ZQuery1.FieldByName('IdPrestMom').AsString);
sql := 'SELECT IdResCasgg FROM restacassagg ORDER BY IdResCasgg DESC LIMIT 1'; Form1.ZQuery1.SQL.Text := sql; Form1.ZQuery1.ExecSQL; Form1.ZQuery1.First; restaCassaNumId:= StrToInt(Form1.ZQuery1.FieldByName('IdResCasgg').AsString);
--- Termina codice ---
Posso risolvere in qualche modo o devo creare tante query quanti sono gli accessi caldi al DB, prima di andare avanti
Penso infatti a come dovrei procedere quando dovrò inserire righe in tabelle diverse, per confermarle o annullarle alla fine di tutti gli inserimenti, pertinenti allo stesso insieme di dati.
xinyiman:
Prova così
--- Codice: --- sql:= 'SELECT movimgg.IdMovvgg AS FROM movimgg ORDER BY IdMovvgg DESC LIMIT 1'; Form1.ZQuery1.SQL.Text:= sql; Form1.ZQuery1.Open; Form1.ZQuery1.First; movimggNumId:= StrToInt(Form1.ZQuery1.FieldByName('IdMovvgg').AsString); Form1.ZQuery1.Close;
sql:= 'SELECT IdPartGlob FROM partmovv ORDER BY IdPartGlob DESC LIMIT 1'; Form1.ZQuery1.SQL.Text:= sql; Form1.ZQuery1.Open; Form1.ZQuery1.First; partmovNumId:= StrToInt(Form1.ZQuery1.FieldByName('IdPartGlob').AsString); Form1.ZQuery1.Close;
sql := 'SELECT IdPrestMom FROM prestmom ORDER BY IdPrestMom DESC LIMIT 1'; Form1.ZQuery1.SQL.Text := sql; Form1.ZQuery1.Open; Form1.ZQuery1.First; prestmomNumId:= StrToInt(Form1.ZQuery1.FieldByName('IdPrestMom').AsString); Form1.ZQuery1.Close;
sql := 'SELECT IdResCasgg FROM restacassagg ORDER BY IdResCasgg DESC LIMIT 1'; Form1.ZQuery1.SQL.Text := sql; Form1.ZQuery1.Open; Form1.ZQuery1.First; restaCassaNumId:= StrToInt(Form1.ZQuery1.FieldByName('IdResCasgg').AsString); Form1.ZQuery1.Close;
--- Termina codice ---
Quando apri un recordset, per poterlo riutilizzare devi chiudere quello precedente. Poi EXECSQL si usa per eseguire una sql che non ritorna valori, se devi recuperare valori devi usare la open (e quindi la close di conseguenza).
DragoRosso:
In generale è buona cosa come ha detto @xinyiman:
1) Chiudere la query; 2) Impostare la sentenza SQL; 3) Aprire la query;
Per Aprire e Chiudere, oltre a Open e Close, si può usare la proprietà Active (True e False). Giusto per la cronaca, ma sconsigliato, si può anche solo impostare la proprietà SQL e poi settare la proprità Active a True senza fare il Close o settare Active a False: ZEOS "chiude" la query automaticamente se si setta la proprietà SQL.
Invece è interessante la necessità riguardante la validazione di una serie di "commit" di un insieme di transazioni singole. Varie scritture su varie tabelle sono molte volte necessarie per completare un sessione di aggiornamento. Ma effettivamente c'è uno "strumento" che consente di effettuare un rollback di tutte le transazioni interessate nel caso qualcosa non vada a buon fine?
In tutti questi anni a me non è mai servito, o meglio non è mai successo alcunchè per cui fosse necessario effettuare un rollback, ma effettivamente se ci fosse lo implementerei sicuramente.
petrusic:
--- Citazione da: xinyiman - Aprile 10, 2021, 06:45:35 pm ---Quando apri un recordset, per poterlo riutilizzare devi chiudere quello precedente.
--- Termina citazione --- Non lo sapevo di certo, ma l'avevo immaginato. Secondo me, Gambas lavora meglio coi DB.
--- Citazione da: xinyiman - Aprile 10, 2021, 06:45:35 pm ---Poi EXECSQL si usa per eseguire una sql che non ritorna valori, se devi recuperare valori devi usare la open (e quindi la close di conseguenza).
--- Termina citazione --- Questo non lo sapevo proprio. Grazie.
Tornando al mio problema, Si, come mi hai suggerito, funziona. l'ho già provato nel pomeriggio, prima che arrivasse la tua risposta. Perciò questa parte di programma posso anche lasciarla come l'ho già modificata, conformemente al tuo suggerimento.
Tuttavia, non risolverei del tutto. Infatti, mi trovo di fronte alla seguente necessità: 1) Devo Inserire righe nuove in una 1.a tabella (movimgg) 2) Devo Inserire righe nuove in una 2.a tabella (prestmom) 3) Devo Inserire righe nuove in una 3.a tabella (restacassagg) 4) Devo Inserire righe nuove in una 4.a tabella (riepmovg) 5) Devo anche aggiornare 2 campi di un'ulteriore 5.a tabella (piancont)
Ma, poichè tutti i dati da inserire hanno la stessa data di calendario, non posso eseguire tante Open con altrettante Close distinte, perchè con la Close, da quanto ho capito, si scatena un Commit automatico. E se mi trovassi, per la manifestazione di un casuale errore, nella necessità di operare un rollback, non sarei più in grado di farlo.
Una realtà del genere significherebbe, per me, dover rinunziare a Zeoslib ed orientarmi su qualcos'altro. Al punto in cui sono arrivato, sarebbe un vero disastro in termini di tempo ed impegno. Spero tanto che ci sia una via d'uscita pratica ed efficace.
petrusic:
--- Citazione da: DragoRosso - Aprile 10, 2021, 10:05:11 pm ---è interessante la necessità riguardante la validazione di una serie di "commit" di un insieme di transazioni singole. Varie scritture su varie tabelle sono molte volte necessarie per completare un sessione di aggiornamento. Ma effettivamente c'è uno "strumento" che consente di effettuare un rollback di tutte le transazioni interessate nel caso qualcosa non vada a buon fine?
--- Termina citazione --- Molto appetibile questa tua indicazione, ma dove potrei trovare la spiegazione sull'argomento?
--- Citazione da: DragoRosso - Aprile 10, 2021, 10:05:11 pm ---In tutti questi anni a me non è mai servito, o meglio non è mai successo alcunchè per cui fosse necessario effettuare un rollback, ma effettivamente se ci fosse lo implementerei sicuramente.
--- Termina citazione --- Personalmente, non mi trovi d'accordo sull'aspettare che l'evento negativo si manifesti per gestirlo. Occorre, secondo me, prevederlo sin dalla progettazione ed inserirne il relativo codice, alfine di non doverci tornare sopra a distanza di tempo, dopo avere, magari, dimenticato la logica dei dettagli del codice scritto.