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!
Titolo: Re:Prima prova db con sqlite RISOLTO
Inserito da: Giuani - Febbraio 19, 2021, 07:37:11 pm
Salve a tutti,
Stavo per aprire un altro topic, ma visto che l’argomento è lo stesso posto qui la mia richiesta.
Leggendo e copiando sul forum sono riuscito a realizzare questa procedure per creare un DB SQLite3:
begin
 SQLite3Connection1.Close;
 SQLite3connection1.DatabaseName:= 'C:\Users\PcHome\Desktop\DBProva\DatiLibri.DB' ;
 SQLite3Connection1.Open;
 SQLTransaction1.Active := true;
 SQLite3Connection1.ExecuteDirect('CREATE TABLE "libri"('+
                    '"ID" Integer NOT NULL PRIMARY KEY AUTOINCREMENT,'+
                    ' "Autore" TEXT(30) NULL,'+
                    ' "Titolo" TEXT(30) NULL,'+
                    ' "Prestato" TEXT(50) NULL,');
end;   
la il programma non da errori in fase di compilazione, ma in runtime, quando si clicca sul button che fa partile la procedura, si mostra una finestra con il seguente messaggio.
“il progetto projct1 ha sollevato una eccezione di classe ‘ESQLDatabaseError’cpn messaggio
SQLite3Connection1: incomplete input.”
Mi potete cortesemente spiegare l‘errore ?
O meglio, è possibile avere una procedura completa di creazione lettura di database SQLite3.
Grazie dell’attenzione. 
Titolo: Re:Prima prova db con sqlite RISOLTO
Inserito da: Stilgar - Febbraio 20, 2021, 12:18:32 pm
Controlla questa stringa
Codice: [Seleziona]
 SQLite3Connection1.ExecuteDirect('CREATE TABLE "libri"('+
                    '"ID" Integer NOT NULL PRIMARY KEY AUTOINCREMENT,'+
                    ' "Autore" TEXT(30) NULL,'+
                    ' "Titolo" TEXT(30) NULL,'+
                    ' "Prestato" TEXT(50) NULL,');
non sembra completa. Finisce per "," e non ")".Così a prima vista.
Titolo: Re:Prima prova db con sqlite RISOLTO
Inserito da: Giuani - Febbraio 20, 2021, 09:39:27 pm
Errore corretto.
Ora cercherò di popolare il db
Grazie
Titolo: Re:Prima prova db con sqlite RISOLTO
Inserito da: Giuani - Febbraio 24, 2021, 08:32:56 pm
Salve,
passo passo ho imparato alcune cose su sqlite3:
-creare un db
-popolare un db,
ora si tratta di connettersi al database.
Ho trovato alcunisemplico esempi di connessione , si collegano senza codice, basta solo ben collegare i vari componenti e tutto ok,
Ma quando cambio il database, e clicco su SQLQUery.Active per portalo a true, si mostra l’errore
SQL3Connection1:  no such table  DATA, dove DATA è il nome della Table specifica di un data base.
Allora, vuol dire che in qualche parte del progetto è memorizzato il nome della Table e va cambiata.
Poiché nell’esempio non ci sono codici, Dov’è questo settaggio ?
Ho provato a modificare SQLQuery1.FieldDefs, ma non capito niente, a volte presenta i campo del database, a volte è vuoto.
Grazie dell’attenzione.
Titolo: Re:Prima prova db con sqlite RISOLTO
Inserito da: Stilgar - Febbraio 25, 2021, 11:58:14 am
Ciao


Menzioni SQLQUery e SQLQuery1.FieldDefs.
Quale delle due è il problema? Viste così sembrano 2 istanza diverse.

Stilgar
Titolo: Re:Prima prova db con sqlite RISOLTO
Inserito da: Giuani - Febbraio 25, 2021, 12:17:36 pm
In effetti sono due
Risolto il primo con
“Bisogna settare SQLQuery1.SQL con il nome della Table”
select * from DATA   
per leggere il data base.
Il secondo è omserire nuovi record, ho fatto questa procedura
procedure TForm1.Button1Click(Sender: TObject);
begin
  If SQLite3Connection1.Connected then
    begin
         SQLQuery2.SQL.Clear;
         SQLQuery2.SQL.Add(Format('insert into DATA (Autore, Titolo, Prestato) values ("%s", "%s","%s")',[Edit1.Text,Edit2.Text,Edit3.Text]));
         SQLQuery2.ExecSQL;
         SQLTransaction1.CommitRetaining;
         SQLQuery1.Refresh;
    end
    else
    begin
     
    end;
end; 
inserisce su i record, ma non quelli di edit.text, inserisce questa ‘(MEMO)’
e poi ogni tanto mi dice SQLite3Connection1 no such table db_castomer, database di un esempio preso in rete e poi adattato al mio progetto.
Credo che anche qui dovrei settare qualche proprietà
Grazie