Italian community of Lazarus and Free Pascal

Programmazione => Databases => Topic aperto da: Golia - Novembre 14, 2020, 05:57:17 pm

Titolo: Prima prova db con sqlite RISOLTO
Inserito da: Golia - Novembre 14, 2020, 05:57:17 pm
Ciao a tutti, la mia prima prova con Lazarus.

Ho fatto il progetto seguendo  la guida " DB concetti fondamentali e connessioni standard" http://www.lazaruspascal.it/index.php?page=140 (http://www.lazaruspascal.it/index.php?page=140).
Ho fatto un db sqlite con una tabella tipo rubrica.
Tutto bene, inserito i componenti descritti e la griglia  DBGrid viene popolata dai dati di sqlite,  posso modificare i dati nella griglia ma non salvare le modifiche nel database, e quando vado a dare il refresh mi da errore: SQLQuery1:Must apply updates before refreshing data.
Il componente "DBNavigator" esegue le funzioni di salvataggio eliminazione inserimento etcc,? o si fa tutto da codice?
C'è qualche esempio o semplice guida per iniziare?
Ho anche letto qui nel forum di "Zeoslib", sembra essere una libreria per facilitare questo lavoro, ma ho letto anche pareri contrastanti. Voi che ne pensate di questa libreria, vale la pena? Premetto che i miei progetti sono semplici.
Vi ringrazio e buona domenica
Titolo: Re:Prima prova db con sqlite
Inserito da: xinyiman - Novembre 14, 2020, 10:45:43 pm
Vado a memoria.Nell'evento After Post del dataset metti il comando

NomeDataSet.ApplyUpdates;

Fammi sapere se risolve.

Titolo: Re:Prima prova db con sqlite
Inserito da: bonmario - Novembre 15, 2020, 08:28:21 am
Ciao,
tieni conto che quello che ti scrivo è frutto di tentativi miei, fino a quando non sono riuscito a scrivere, quindi non so se è il metodo più ortodosso !!!

Avrai un oggetto di tipo "TSQLQuery", che nel mio codice chiamerò "SQLQuery1".
Prima di eseguire "SQLQuery1.Open", ho messo questo:
Codice: [Seleziona]
        //Per poter modificare i record tramite DBNavigator1, ho bisogno delle seguenti opzioni:
     with SQLQuery1 do begin
        ReadOnly:=False;
        //UsePrimaryKeyAsKey:=False;
        UsePrimaryKeyAsKey:=True;
        PacketRecords:=-1; //https://wiki.freepascal.org/mssqlconn#Error_20019_:_Attempt_to_initiate_a_new_Adaptive_Server_operation_with_results_pending
        UpdateMode:=upWhereChanged;
     end;

Ho poi aggiunto la gestione dell'evento "SQLQuery1AfterPost", che ho compilato così:
Codice: [Seleziona]
  //Usata quando (TipoApertDB = tadScrivi)
  try
    SQLQuery1.ApplyUpdates;
    if (1 = 2) then begin
      SQLTransaction1.Commit; //A differenza di CommitRetaining, chiude la conenssione subito dopo aver committato
      GestVislTabella(Self);  //Visto quanto scritto qui sopra, ricarico la tabella
    end else begin
      SQLTransaction1.CommitRetaining; //Fa la commit, e tiene attiva la connessione
    end;
  except
    on E: Exception do begin
      EmettiErrore(0, 'ERRORE: ' +
                      LineEnding +
                      E.Message);
      //Ricarico i dati della tabella.
      //Se non lo facessi, l'utente vedrebbe in griglia anche i valori che non sono stati salvati !!!
      GestVislTabella(Self);
    end;
  end;

Ripeto: non so se sia il metodo più corretto, ma funziona.

P.S. Per quanto riguarda il componente Zeos, io sono uno di quelli che non lo usa, e fino ad ora me la sono cavata senza !!!

Ciao, Mario
Titolo: Re:Prima prova db con sqlite
Inserito da: Golia - Novembre 15, 2020, 05:31:00 pm
Ciao, intanto vi ringrazio tutti e due
@xinyiman ho fatto così:
Codice: [Seleziona]
procedure TForm1.SQLQuery1AfterPost(DataSet: TDataSet);
begin
       SQLQuery1.ApplyUpdates();
end; 
Non mi da più errore ma non va ancora a modificare il database

@bonmario perdonami ma sono proprio ai primi passi. Non ho scritto codice, ho fatto tutto da grafica. Non so dove "incastrare" il tuo codice, in unit1 non trovo "SQLQuery1.Open" perchè appunto credo venga eseguito dai componenti. vedo di studiare non mollo.
Titolo: Re:Prima prova db con sqlite
Inserito da: xinyiman - Novembre 15, 2020, 06:50:18 pm
Dopo l'applyupdate hai fatto il commit della transazione?
Titolo: Re:Prima prova db con sqlite
Inserito da: Golia - Novembre 15, 2020, 07:44:10 pm
No ho fatto come da guida.
Adesso ho provato ad aggiungere
Codice: [Seleziona]
  SQLTransaction1.Commit; 
Niente.
Titolo: Re:Prima prova db con sqlite
Inserito da: xinyiman - Novembre 15, 2020, 09:01:17 pm
Prova ad allegare un esempio e vedrò di correggerlo
Titolo: Re:Prima prova db con sqlite
Inserito da: Golia - Novembre 16, 2020, 02:26:03 am
Ti ringrazio
Ho compattato la cartella del progetto togliendo l'eseguibile spero vada bene.
Grazie mille spero poi di partire in quarta  :D
Titolo: Re:Prima prova db con sqlite
Inserito da: bonmario - Novembre 16, 2020, 07:57:25 am
@bonmario perdonami ma sono proprio ai primi passi. Non ho scritto codice, ho fatto tutto da grafica. Non so dove "incastrare" il tuo codice, in unit1 non trovo "SQLQuery1.Open" perchè appunto credo venga eseguito dai componenti. vedo di studiare non mollo.

Prima segui le altre risposte, se poi non riesci a sistemare, leggi questo: se mischi le cose rischi poi di confonderti !!!
Scusa, io di solito faccio le impostazioni da codice, e non dall'object inspector, tu invece stai facendo il contrario. Non è sbagliato, è solo questione di abitudine.
Tra i vari oggetti che hai dichiarato, c'è anche un "SQLQuery1".
Devi impostare le proprietà di quell'oggetto, come ti ho scritto nel post precedente.

Ciao, Mario
Titolo: Re:Prima prova db con sqlite
Inserito da: xinyiman - Novembre 16, 2020, 08:29:20 am
Allora con poche semplici modifiche funziona. Se vuoi puoi ignorare il form create e il form destroy, ma io preferisco caricare le connessioni così.
Poi ti bastava aggiungere la linea

Self.SQLTransaction1.CommitRetaining;

La differenza tra Commit e CommitRetaining è che la prima salva i dati e chiude la connessione, la seconda salva i dati e mantiene la connessione aperta.

Codice: [Seleziona]
procedure TForm1.SQLQuery1AfterPost(DataSet: TDataSet);
begin
     Form1.SQLQuery1.ApplyUpdates();
     Self.SQLTransaction1.CommitRetaining;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
     Self.SQLite3Connection1.DatabaseName := Application.Location + 'prova1.db';
     Self.SQLite3Connection1.Open;
     Self.SQLTransaction1.Active:=true;
     Self.SQLQuery1.SQL.Text:='select * from clienti order by cognome ;';
     Self.SQLQuery1.Open;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
     if Self.SQLQuery1.Active then
        Self.SQLQuery1.Close;

     if Self.SQLTransaction1.Active then
        Self.SQLTransaction1.Active := false;

     if Self.SQLite3Connection1.Connected then
        Self.SQLite3Connection1.Close();
end; 
Titolo: Re:Prima prova db con sqlite
Inserito da: Golia - Novembre 16, 2020, 05:02:14 pm
Grazie mille del vostro tempo
Stasera mi guardo bene e vi faccio sapere
Ciao
Titolo: Re:Prima prova db con sqlite
Inserito da: Golia - Novembre 16, 2020, 07:07:03 pm
@xinyiman funziona! Grazie adesso mi sembra già di vedere il percorso in discesa  :)

@ Mario ho fatto i miei progetti con il linguaggio Gambas e anch'io mi trovo scrivendo da codice. Adesso devo un po'imparare e sicuramente avrò ancora bisogno ;D

Grazie mille
Titolo: Re:Prima prova db con sqlite RISOLTO
Inserito da: xinyiman - Novembre 16, 2020, 07:29:09 pm
Figurati, ho creato il forum per questo motivo :)
Titolo: Re:Prima prova db con sqlite RISOLTO
Inserito da: Golia - Novembre 16, 2020, 09:26:03 pm
Stupendo funziona anche con postgres!