Italian community of Lazarus and Free Pascal

Programmazione => Databases => Topic aperto da: sergio - Aprile 17, 2021, 07:31:18 pm

Titolo: [Risolto] Sqlite3 errore nelle ricerche
Inserito da: sergio - Aprile 17, 2021, 07:31:18 pm
Buonasera a tutti , spero che possiate aiutarmi .Nel programma che sto preparando  utilizzo Sqlite3 . Mi sorge un problema , quando vado a  eseguire  una ricerca :   
SQLQuery1.SQL.Text:= 'SELECT * FROM '+Archivio+' WHERE Intest ='''+ Edit2.Text + ''';';
 SQLQuery1.Open;
mi si blocca il programma se Edit2.Text contiene un ( ' )  Apostrofo .
Sapete come poter aggirare il problema ?  La variabile  nel database è una Varchar().
Vi ringrazio anticipatamente ! :)
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: DragoRosso - Aprile 17, 2021, 07:54:01 pm
Se nel testo della query c'è un apostrofo, per usarlo lo devi duplicare.

Quindi devi cercare gli apostrofi in Edit2.text e per ogni apostrofo devi inserirne un altro.

Ciao
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: sergio - Aprile 17, 2021, 08:19:11 pm
ciao , scusa ma io ho provato a usare Replace( miastringa, '' ' '' , '' ' ' '' ) ma  mi da l'errore perche '' ' '' non me lo prende . sai come fare ? Grazie
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: nomorelogic - Aprile 17, 2021, 08:26:38 pm
non l'h oprovato ma così dovrebbe andare

Codice: [Seleziona]
 Replace( miastringa, '''', '''''')
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: DragoRosso - Aprile 17, 2021, 09:49:48 pm
Un consiglio:

quando lavorate con il carattere apostrofo, a codice è meglio che non compaia.

Semplicemente usa questa forma:

Codice: [Seleziona]
ReplaceStr(miastringa, #39, #39#39);

Semplice, visibile e non crea problema alcuno.

Ciao

P.S.: ovvio che come delimitatore di stringa deve essere usato !!!  ;D
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: brunello - Aprile 17, 2021, 10:14:43 pm
ma non è più semplice con
Codice: [Seleziona]
quotedstr(testo)
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: DragoRosso - Aprile 17, 2021, 10:24:19 pm
(?? Si, quello è ancora più veloce ??).

In effetti non usavo quella funzione da tanto tempo, me ne ero dimenticato completamente.  ;)

P.S.:
ma non è più semplice con
Codice: [Seleziona]
quotedstr(testo)

Ahhhh, ecco perchè non la usavo: inserisce i caratteri apostrofo anche in testa ed in coda alla stringa .......


Può essere usata direttamente così:

Codice: [Seleziona]
SQLQuery1.SQL.Text:= 'SELECT * FROM '+Archivio+' WHERE Intest = '+QuotedStr(Edit2.Text)+';';
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: SB - Aprile 18, 2021, 10:44:09 am
Ti sconsiglio vivamente di usare l'input dell'utente per costruire una query SQL
L'apostrofo potrebbe essere l'ultimo dei problemi
Usa piuttosto le query parametriche
Se proprio vuoi costruire la query usando l'input, ripuliscilo da tutti i caratteri che non siano lettere, cifre e pochi altri
Non lasciare alcun carattere che possa avere un qualche significato per SQL


SQLQuery1.SQL.Text:= 'SELECT * FROM '+Archivio+' WHERE Intest ='''+ Edit2.Text + ''';';
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: nomorelogic - Aprile 18, 2021, 11:40:12 am
visto che ci siamo io spesso utilizzo questo modo
soprattutto quando voglio costruire una stringa con molti parametri
rimane piuttosto manutenibile anche quando un parametro stringa deve diventare numero  o viceversa

Esempio stringa -> integer: '... ''%s'' ...'
diventa '... %d ...'


Codice: [Seleziona]
SQLQuery1.SQL.Text:= Format('SELECT * FROM Archivio WHERE Intest =''%s'';', [ Edit2.Text ]');
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: DragoRosso - Aprile 18, 2021, 12:26:48 pm
visto che ci siamo io spesso utilizzo questo modo
soprattutto quando voglio costruire una stringa con molti parametri
rimane piuttosto manutenibile anche quando un parametro stringa deve diventare numero  o viceversa

Esempio stringa -> integer: '... ''%s'' ...'
diventa '... %d ...'


Codice: [Seleziona]
SQLQuery1.SQL.Text:= Format('SELECT * FROM Archivio WHERE Intest =''%s'';', [ Edit2.Text ]');

Uhmmm, non sono convinto che funzioni ... ciò che hai scritto, nel caso Edit2 contenga caratteri "speciali" in primis l'apostrofo ritorniamo all'argomento del topic. Non ho provato e forse mi sbaglio.

Io sono abituato, ma è questione di stile e di necessità, intanto a filtrare come dice @SB il contenuto degli input utenti (è per questo che uso sempre replacestr e non qutoedstr). I filtri in genere applicati sono l'inserimento degli escape (carattere che dipende dal database ma che generalmente è il "\") davanti a tutti i caratteri "_" e "%" (che hanno un particolare significato sopratutto nel LIKE), il carattere apostrofo come indicato in questi post, e alle volte anche altri caratteri o parole intere (faccio un esempio di ',' o JOIN, GROUP, ALTER, ESCAPE, etc...) dipendente dal contesto.

In genere poi non uso a codice i caratteri "da tastiera" ma uso i codici letterali (ad esempio non ' ma bensi #39)

Quanto sopra è stato necessario perchè in diversi grossi gruppi, alcuni software che ho fornito sono stati testati contro l'SQL INJECTION e quindi applicare quelle accortezze era il minimo indispensabile.

Diciamo che in genere queste accortezze sono sovraabbondanti, ma dipende sempre dal contesto d'uso.

Saluti
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: nomorelogic - Aprile 18, 2021, 12:50:24 pm
la formattazione avviene nell'array dei parametri
la stringa con la select sql rimane pulita e senza concatenazioni


Edit:
da provare ma con la quote dovrebbe diventare
Codice: [Seleziona]
SQLQuery1.SQL.Text:= Format('SELECT * FROM Archivio WHERE Intest = %s;', [ QuotedStr(Edit2.Text) ]');
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: nomorelogic - Aprile 18, 2021, 03:07:41 pm
Non vorrei che ne uscisse della confusione.
Format non sostituisce gli apostrofi ma utilizzata come ho scritto in "Edit" del post precedente (e cioè con QuoteStr nell'array dei parametri) può essere utile per scrivere in modo chiaro e manutenibile anche una sql complessa con i quote.
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: brunello - Aprile 18, 2021, 03:26:00 pm
per me la soluzione più pulita è questa
Codice: [Seleziona]
SQLQuery1.SQL.Text:= 'SELECT * FROM Archivio WHERE Intest =:par1';
SQLQuery1.ParamByName('par1').Value := Edit1.text;
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: DragoRosso - Aprile 18, 2021, 04:01:00 pm
@nomorelogic
Ho eliminato l'ultimo mio post che poteva creare assoluta confusione e si basava su una "deduzione" non verificata.
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: sergio - Aprile 18, 2021, 06:20:41 pm
Ragazzi , vi ringrazio , ho provato tutte el soluzioni da voi proposte , ma purtroppo quando arrivo all'esecuzione di SQLQuery.Open mi va in errore .
Posto il pezzo di programma , se qualcuno riesce a capire come mai . evidenzio in rosso la Query dove si blocca , vi ringrazio anticipatamente !
 VAR
  Archivio : Ansistring ;
  begin
  if ComboBox1.Text = 'Clienti' Then
  begin
  Archivio := 'Clienti' ;
  SQLite3Connection1.Connected:= False;
 SQLite3Connection1.DatabaseName:= Application.Location + 'archivi'+System.DirectorySeparator+'Clienti.db';
 SQLite3Connection1.Connected:= True ;
  end;
  If ComboBox1.Text = 'Fornitori' Then
  begin
  Archivio := 'Fornitori' ;
  SQLite3Connection1.Connected:= False;
 SQLite3Connection1.DatabaseName:= Application.Location + 'archivi'+System.DirectorySeparator+'Fornitori.db';
 SQLite3Connection1.Connected:= True ;
  end;
  If Edit1.Text = '' then
  if (Edit2.Text <> '')THEN       //and(Edit1.Text = '') then
    Begin
    SQLQuery1.SQL.Text:= 'SELECT * FROM "'+Archivio+'" WHERE Intest = QuotedStr(Edit2.Text) ';
    //   '+ComboBox1.Text+'AND codice = '+Edit1.Text+';' ;
  //  StringGrid1.RowCount:=1;

    SQLQuery1.Open;
      while not SQLQuery1.EOF do
      begin
      if SQLQuery1.Fields[1].Text = Edit2.Text then
       begin
       Edit1.Text:= SQLQuery1.Fields[0].Text;     // codice
       Edit3.Text:= SQLQuery1.Fields[2].Text;     //indirizzo
       Edit4.Text:= SQLQuery1.Fields[3].Text;     // cap
       Edit5.Text:= SQLQuery1.Fields[4].Text;     // citta
       Edit6.Text:= SQLQuery1.Fields[5].Text;    // Nazione
       Edit7.Text:= SQLQuery1.Fields[6].Text;     // telefono1
       Edit8.Text:= SQLQuery1.Fields[7].Text;     // telefono2
       Edit9.Text:= SQLQuery1.Fields[8].Text;      //p.iva
       Edit10.Text:= SQLQuery1.Fields[9].Text;    //cod fisc.
       Edit11.Text:= SQLQuery1.Fields[10].Text;   //  pec
       Edit12.Text:= SQLQuery1.Fields[11].Text;    //codice sdi
       Edit13.Text:= SQLQuery1.Fields[12].Text;   // Provincia

    //    StringGrid1.RowCount:=StringGrid1.RowCount+1;
    //    StringGrid1.Cells[2, StringGrid1.RowCount-1]:=SQLQuery1.Fields[2].Text;
    //    StringGrid1.Cells[3, StringGrid1.RowCount-1]:=SQLQuery1.Fields[0].Text;
    //    StringGrid1.Cells[1, StringGrid1.RowCount-1]:=SQLQuery1.Fields[1].Text;
    //    StringGrid1.Cells[4, StringGrid1.RowCount-1]:=SQLQuery1.Fields[5].Text;
        SQLQuery1.Next;
        end ;
      end;
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: DragoRosso - Aprile 18, 2021, 09:30:06 pm
    SQLQuery1.SQL.Text:= 'SELECT * FROM "'+Archivio+'" WHERE Intest = QuotedStr(Edit2.Text) ';

Prima e dopo Archivio usi si le virgolette che l'apostrofo. Poi QuotedStr và fuori la stringa. Termina il tutto con ';' Se ci sono errori ancora, metti anche li QuotedStr(Archivio).

Codice: [Seleziona]
 SQLQuery1.SQL.Text:= 'SELECT * FROM '+Archivio+' WHERE Intest = '+QuotedStr(Edit2.Text) +';';

Poi dopo la Open, conviene sempre inserire un FIRST (cursore alla prima riga).

Ciao
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: Stilgar - Aprile 19, 2021, 12:57:04 am
per me la soluzione più pulita è questa
Codice: [Seleziona]
SQLQuery1.SQL.Text:= 'SELECT * FROM Archivio WHERE Intest =:par1';
SQLQuery1.ParamByName('par1').Value := Edit1.text;


La soluzione proposta da Brunello non l'hai provata?


A me sembra possa toglierti dai guai.
(Ed è quella più pulita in assoluto).


Stilgar
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: DragoRosso - Aprile 19, 2021, 01:12:40 am
per me la soluzione più pulita è questa
Codice: [Seleziona]
SQLQuery1.SQL.Text:= 'SELECT * FROM Archivio WHERE Intest =:par1';
SQLQuery1.ParamByName('par1').Value := Edit1.text;


La soluzione proposta da Brunello non l'hai provata?


A me sembra possa toglierti dai guai.
(Ed è quella più pulita in assoluto).


Stilgar

Archivio non è la tabella 'Archivio', è la variabile stringa ... il nome della tabella è 'Fornitori'.

Il codice di Brunello sarà (non conosceo l'uso dei parametri quindi non sò se quella parte è corretta):
Codice: [Seleziona]
SQLQuery1.SQL.Text:= 'SELECT * FROM '+Archivio+' WHERE Intest =:par1';
SQLQuery1.ParamByName('par1').Value := Edit2.text;
[/quote]

'Notte
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: Stilgar - Aprile 19, 2021, 09:16:22 am
Allora farei una cosa del genere:

Codice: [Seleziona]
sql := Format(SELECT * FROM %s WHERE Intest =:par1',[Archivio]);


In questo modo la lettura della stringa resta abbastanza buona e si può trovare eventuali errori di battitura.


Stilgar
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: brunello - Aprile 19, 2021, 09:33:13 pm
per evitare di enumerare tutti i santi del paradiso prima di chiamare la
Codice: [Seleziona]
sqlquery1.open
// inserisco questa comando
sqlquery1.sql.savetofile('errore.sql');
nel caso in cui utilizzo i parametri occorre utilizzare questa piccola procedura per salvare anche i parametri associati che altrimenti andrebbero persi
Codice: [Seleziona]
procedure TDati.SalvaQuery(vDati: TQuery; nomefile: string);
var
  lista: TStringList;
  i: Integer;
begin
  lista := TStringList.Create;
  lista.Assign(vDati.SQL);
  for i := 0 to vDati.Params.Count -1 do
    lista.Add(vDati.Params[i].Name + ' = ' + VarToStr(vDati.Params[i].Value));
  lista.SaveToFile(nomefile);
  lista.Free;
end;
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: sergio - Aprile 20, 2021, 08:27:45 am
Grazie a tutti , faccio alcune prove e vi comunicherò il risultato . Purtroppo prima del fine settimana non riesco a lavorarci sopra .Grazie mille  !
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: sergio - Aprile 21, 2021, 08:14:23 pm
Grazie mille a tutti per i vari suggerimenti , tutti molto apprezzati ! Ho provato il il sistema suggerito da Brunello che per le mie capacità è risultato il più semplice e  funziona perfettamente.
Volevo chiedere comunque se c'era la possibilità di modificare 
Citazione
SQLQuery1.SQL.Text:= 'SELECT * FROM '+Archivio+' WHERE Intest =:par1';
SQLQuery1.ParamByName('par1').Value := Edit2.text;
         

per  mettere un Like che consenta la ricerca anche se non si digitalizza l'intera stringa ricercata !
io ho provato a mettere
 
Citazione
SQLQuery1.SQL.Text:= 'SELECT * FROM '+Archivio+' WHERE Intest LIKE:par1';
SQLQuery1.ParamByName('par1').Value := Edit2.text;
la ricerca funziona sempre, ma solo se il parametro ricercato stringa è perfettamente uguale a quello nel db.
Grazie anticipatamente
 
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: DragoRosso - Aprile 21, 2021, 09:39:46 pm
Ciao,
devi  usare i pattern % oppure _ per la ricerca:

%po ricerca pippo peppo troppo lampo

po% ricerca polipo polpetta polifemo

tr_ppo ricerca troppo treppo trippo

Ovviamente puoi usarli anche insieme.

https://www.sqlitetutorial.net/sqlite-like/ (https://www.sqlitetutorial.net/sqlite-like/)

Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: sergio - Aprile 23, 2021, 08:03:38 pm
Ciao DragoRosso scusa , ma in questa Query
Citazione
    SQLQuery1.SQL.Text:= 'SELECT * FROM '+Archivio+' WHERE Intest Like :intest';
    SQLQuery1.ParamByName('intest ').Value := Edit2.text;

dove intest è il nome del campo del database , mentre Edit2.Text è il dato da ricercare .
come li inseriresti i pattern % ????
Io ho provato, ma non riesco a trovare il modo .
Un  aiuto mi sarebbe molto utile !
Se qualcuno potesse darmi una dritta ,  grazie mille ! :-[
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: DragoRosso - Aprile 23, 2021, 08:19:03 pm
...... mentre Edit2.Text è il dato da ricercare .
come li inseriresti i pattern % ????

Porprio li, in Edit2.TEXT.
Esempio:
Codice: [Seleziona]
Edit2.Text := 'fa%';

Ricerca nelle righe la cui colonna Intest ha un valore che inizia per 'fa', come fattoria, farina, fagiolo .......

Ciao
Titolo: Re:Sqlite3 errore nelle ricerche
Inserito da: sergio - Aprile 24, 2021, 01:18:44 pm
Grazie  mille !  Ho risolto mettendo
 
Citazione
   SQLQuery1.SQL.Text:= 'SELECT * FROM '+Archivio+' WHERE Intest like :Intest';
    SQLQuery1.ParamByName('Intest').Value := '%'+Edit2.Text+'%';
Grazie mille a tutti per l'aiuto e la pazienza avuta !! :-[