SQLite Errore in SELECT WHERE

di il
9 risposte

SQLite Errore in SELECT WHERE

Buona sera a tutti

In un programma ho scritto una Function  che testa l'esistenza di un record della tabella in un DB  SQLite

Le istruzioni sono:

DIM Query as String = "SELECT * FROM Tmacro  WHERE  Codmacro LIKE  @cerca;"

Using comando As New SQLiteCommand(Query, connessione)

comando.Parameters.AddWithValue("@cerca", codUTF8)

Using Leggi As SQLiteDataReader = comando.ExecuteReader

Non trova il record e la funzione termina con False

Cercando di capire il problema ho deciso di leggere tutta la tabella ed ad ogni elemento eseguire il test

ho modificato :

DIM Query as String = "SELECT * FROM Tmacro  ;"

e adesso mi trova l'elemento cercato.

La tabella Tmacro è formata da due campi, ID integer (chiave) e CodMacro  Strings

Dove sbaglio?

Accludo il codice della funzione

Private Function TestExistMacro(tempcod As String) As Boolean
        Dim Nome As String, Iden As Integer

        Nome = " "
        Dim codUTF8 As String = UTF16toUTF8(tempcod)   ' converte da UTF16 a UTF8
        
        Try
            Using connessione As New SQLiteConnection(ConnString)
                connessione.Open()

                'Dim Query As String = "SELECT * FROM Tmacro WHERE Codmacro LIKE @cerca;"
                Dim Query As String = "SELECT * FROM Tmacro;"
                Using comando As New SQLiteCommand(Query, connessione)
                    '    comando.Parameters.AddWithValue("@cerca", codUTF8)
                    Using Leggi As SQLiteDataReader = comando.ExecuteReader
                        Try
                            While Leggi.Read()
                                Iden = Leggi.GetInt32(0)
                                Nome = Leggi.GetString(1)
                                Nome = Nome.Trim
                                If Nome Is Nothing Then
                                    Continue While
                                End If
                                If Nome = codUTF8 Then
                                    Return True
                                    Exit Function
                                End If
                            End While
                        Catch ex As Exception
                            MsgBox("Errore Leggi.read: " & ex.Message)
                            Return False
                            Exit Function
                        End Try
                    If Nome Is Nothing Or Nome IsNot codUTF8 Then
                                Return False
                                Exit Function
                            End If
                        End Using

                End Using
            End Using
            Return True
        Catch ex As Exception
            MsgBox("Errore su Test: " & ex.Message)
            Return False
            Exit Function
        End Try
        Return True
    End Function

Grazie per l'attenzione

Franco

9 Risposte

  • Re: SQLite Errore in SELECT WHERE

    17/02/2025 - Frankq ha scritto:

    Dove sbaglio?

    Ciao, diciamo che ci sono diversi "sbagli".  ;-)

    Private Function TestExistMacro(tempcod As String) As Boolean
    	' Set convert Utf mode
        Dim codUTF8 As String = UTF16toUTF8(tempcod) ' converte da UTF16 a UTF8
        Try
        	'Open connection
            Using connessione As New SQLiteConnection(ConnString)
                connessione.Open()
    			' Set sqlstring
                Dim Query As String = "SELECT 1 FROM Tmacro WHERE Codmacro LIKE @cerca LIMIT 1;"
                ' Set command
                Using comando As New SQLiteCommand(Query, connessione)
                    ' Set parameters
                    comando.Parameters.AddWithValue("@cerca", "%" & codUTF8 & "%")
    				' Execute reader and return value
                    Using Leggi As SQLiteDataReader = comando.ExecuteReader()
                        Return Leggi.Read() ' se trova almeno un risultato, restituisce True
                    End Using
                End Using
            End Using
        Catch ex As Exception
        	' Display erroe exception
            MsgBox("Errore su TestExistMacro: " & ex.Message)
            Return False
        End Try
    End Function
    

    Dimmi una cosa....

    come mai il mio codice è assai più corto del tuo ?

    Devi approfondire :

    • come scrivere in SQL le tue stringhe
    • se  devi controllare se esiste un record :
      • SELECT 1 FROM Tmacro... inutile leggere tutte le fields se devo testarne una sola
      • LIMIT 1 ... inutile andare avanti nella ricerca quando basta aver trovato la prima occorrenza e uscire da Sql.
      • "@cerca", "%" & codUTF8 & "%" ... le ricerche con  il Like si effettuano con l'ausilio del carattere "%" che indica la modalità di ricerca:
        • "@cerca", "%" & codUTF8 & "%" : ricerca se CONTIENE
        • "@cerca", "%" & codUTF8"  : ricerca se "TERMINA CON"
        • "@cerca", codUTF8 & "%" : ricerca se "INIZIA CON"
    • Come controllare l'esito della ricerca
      • Read() restituisce direttamente True se trova almeno una corrispondenza, quindi non serve salvare il nome ed eseguire dei confronti
      • Exit Function non verrà mai eseguito : il Return provvede a terminare la function con l'esito della ricerca (True per trovato, altrimenti ritorna False)
      • While Leggi.Read() : non serve!!!
        • se devi validare altre condizioni allora le inserisci direttamente nella stringa SQL. Farle manualmente non ha senso
    • Commenti :
      • Commentare sempre il codice in tutte le sue parti per renderlo rileggibile ad altri e anche a distanza di tempo per te stesso
    • e poi....
      • basta dai... leggi e confronta le due versioni di codice e approfondisci gli argomenti qui sopra riportati

    .
    Verifica il codice sopra riportato e implementa ciò che ti occorre...


    Nota: 

    Purtroppo oggi i computer sono troppo veloci e non si cerca più di ottimizzare il codice per avere delle performance ottimali.

    Se vuoi veramente imparare qualcosa dovresti usare almeno un computer di 20 o 30 anni fa... in tali circostanze sei "obbligato" a scrivere ottimizzando il codice e approfondendo argomenti di varia natura. Mentre con i computer di oggi viene a meno tale stimolo... e si studiano approcci/metodi in modo molto superficiale.

    Quindi se posso darti un consiglio... non soffermarti mai al primo approccio per la soluzione da adottare, cerca sempre se esistono approcci diversi e più performanti per risolvere lo stesso problema.
    Questo ti permette di approfondire e studiare argomenti che altrimenti non prenderesti mai in considerazione.

  • Re: SQLite Errore in SELECT WHERE

    Dovendo leggere una sola colonna di una sola tabella non è necessario impegnare un DataReader. Meglio usare ExecuteScalar che restituisce Nothing se la condizione WHERE non è soddisfatta.

    Leggi sulla guida  i dettagli su questo metodo e ricavane il nuovo codice. Le buone regole del forum sconsigliano di postare codice risolutivo completo (c.d. "pappa pronta"). 

  • Re: SQLite Errore in SELECT WHERE

    18/02/2025 - grumpy ha scritto:

    Dovendo leggere una sola colonna di una sola tabella non è necessario impegnare un DataReader. Meglio usare ExecuteScalar che restituisce Nothing se la condizione WHERE non è soddisfatta.

    Ciao, se  non ha bisogno di leggere più righe  l' ExecuteScalar  va sicuramente bene ed è l'approccio migliore.

    Ma da come l'OP ha impostato il suo codice che con la while legge i records risultanti per eseguire ulteriori controlli, il metodo rimane quello, almeno  fino a quando l'OP decida di eseguire tutti i controlli nella stringa SQL.  Allora solo in questo caso l' ExecuteScalar è la soluzione preferibile.

    Insomma, il mio solo un semplicissimo "ESEMPIO" per far capire i diversi errori, sia di scrittura del codice che di logica, rispettando e mantenendo la traccia che l'Op ha già impostato. A tal fine a  corredo è stato fornito una serie di spiegazioni e di consigli di come strutturare il suo codice e quali approfondimenti/studi siano necessari intraprendere.

    Per dare una soluzione definitiva "pappa pronta" occorrerebbe che l'OP fornisca una analisi più esaustiva di ciò che vuol fare.
    Diversamente si rimane nel campo degli esempi, consigli e ipotesi.

    ;-)

  • Re: SQLite Errore in SELECT WHERE

    Cari amici, vi ringrazio per la vostra partecipazione.

    Ho 78 annni e faccio parte di una associazione di volontari ODV nel campo della promozione culturale; per l'associazione mi occupo del settore informatico

    ho sempre utilizzato il VB6 ma, visto che primo o poi dovrò passare il testimone ho iniziato con Visual Studio e VB Net.  Ho scritto questo programma  sulla falsa riga di ciò che ho capito nei video e nei post che ho trovato in rete.  L'obbiettivo è di far girare il programma e poi sfrondarlo e ottimizzarlo, inserendo tutti i commenti che possono aiutare  chi lo gestirà.

    Non avevo capito l'uso di % in @cerca, adesso farò varie prove; mi serve la  funzionalità esiste si-no  e anche  estrarre tutti gli elementi che cominciano per 

    Questo programma di inizio è per un amico radioamatore e autocostruttore.  Deve analizzare un file di testo con le specifiche di un PCB e crea un file Gcode per pilotare una CNC e forare il PCB.

    Legge le librerie delle macro e crea un DB

    Analizza il file del PCB e accedendo al Db  ricalcola la posizione dei fori e genera il Gcode

    Franco

  • Re: SQLite Errore in SELECT WHERE

    18/02/2025 - Frankq ha scritto:

    Legge le librerie delle macro e crea un DB

    Analizza il file del PCB e accedendo al Db  ricalcola la posizione dei fori e genera il Gcode

    Ciao,

    se devi leggere più record risultanti dalla LIKE allora nella SELECT :

    • togli dalla Sql il LIMIT 1
    • metti i nomi delle Fields oppure *
      • a seguire del ExecuteReader rimetti  il While per verificare e controllare tutti i records restituiti dalla Sql

    ESEMPIO:

    		Dim Query As String = "SELECT * FROM Tmacro WHERE Codmacro LIKE @cerca;"
                ' set command
                Using comando As New SQLiteCommand(Query, connessione)
                    ' set parameters
                    comando.Parameters.AddWithValue("@cerca", "%" & codUTF8 & "%")
                    ' execute reader
                    Using Leggi As SQLiteDataReader = comando.ExecuteReader()
                        ' check if there are records
                        While Leggi.Read()
                            ' example
                            ' Dim valore As String = Leggi("NomeColonna").ToString()
                            Return True Oppure False secondo  i tuoi controlli
                        End While
                    End Using
                End Using


    Ricorda che essendo una Function che ritorna un valore Booleano, il "Return" ti permette di uscire immediatamente dalla funzione con il valore da restituire.
    Quindi non usare l' Exit Function che potrebbe solo generarti un errore in quanto non avrai un valore di ritorno.

    Poi se hai altre cose da verificare, chiedi pure senza problemi.

  • Re: SQLite Errore in SELECT WHERE

    18/02/2025 - Frankq ha scritto:

    Ho 78 annni

    ....e vabbè, sei un ragazzino, ne ho molti molti più di te ;-)

  • Re: SQLite Errore in SELECT WHERE

    17/02/2025 - Frankq ha scritto:

    Dim codUTF8 As String = UTF16toUTF8(tempcod) ' converte da UTF16 a UTF8

    Questa riga - che viene mantenuta nei vari esempi, anche quelli successivi - a cosa dovrebbe servire?

  • Re: SQLite Errore in SELECT WHERE

    @Alka

    Visual Studio codifica UTF16  mentre SQLite memorizza i dati in UTF8. Questa routine converte le stringhe da UTF16 a UTF8. Vedi il mio post precedente 

    Franco

  • Re: SQLite Errore in SELECT WHERE

    19/02/2025 - Frankq ha scritto:

    Visual Studio codifica UTF16  mentre SQLite memorizza i dati in UTF8. Questa routine converte le stringhe da UTF16 a UTF8. Vedi il mio post precedente 

    Visual Studio non "codifica" nulla, al massimo è il runtime di .NET che salva le stringhe in memoria utilizzando l'encoding UTF-16.

    Detto questo, di fatto la tua conversione (di cui non mi sembra di aver visto il codice) prende un System.String e restituisce un System.String, quindi prendendo in esame il codice originale qui di seguito

    Dim codUTF8 As String = UTF16toUTF8(tempcod) ' converte da UTF16 a UTF8

    la variabile codUTF8 è ancora in UTF-16.

    Quando la passi come valore al parametro richiesto dalla query con questa riga

    comando.Parameters.AddWithValue("@cerca", "%" & codUTF8 & "%")

    stai sempre concatenando stringhe "letterali" UTF-16 con una variabile (codUTF8) che è un riferimento a un buffer che contiene una stringa UTF-16, poiché questo è il formato che .NET usa in memoria per rappresentare stringhe, salvo ove diversamente specificato.

    Se SQLite si attende un encoding diverso, è il driver di accesso ai dati che essendo consapevole di questa condizione trasforma la stringa originale UTF-16 nell'encoding desiderato (UTF-8), ma tu non devi fare nulla.

    Sarebbe interessante vedere cosa fa quella funzione "UTF16toUTF8" perché, per i motivi sopra e a meno che non abbia tralasciato qualcosa, si direbbe del tutto superflua e probabilmente inefficace, da cui la mia curiosità iniziale. Ipotizzo che magari sia un refuso di codice di esempio proveniente da qualche suggerimento di ChatGPT (o affine) e preso "così com'è" senza le dovute verifiche.

    Ciao! :)

Devi accedere o registrarti per scrivere nel forum
9 risposte