Mysql e Query, Problema Encoding?

Ciao a tutti,

non so se vi capitato ma devo eseguire una query su MySQL. La medesima query su phpmydqmin funziona da Xojo non funziona.

Premessa:

Il database di tipo: utf8_general_ci
la tabella ha un enconding: utf8_general_ci

Nella connessione a DB ho impostato:

db.SQLExecute("set names utf8")

Per eseguire la query ho fatto questo:

  
  Dim query as String 
  query = "SELECT * FROM atleta WHERE upper(concat(cognome , ' ' , nome)) = '" 
  query = query + Uppercase(nomeCognome.ConvertEncoding(Encodings.UTF8).Trim) + "'"
  
  
  dim connettore as New Connettore
  if connettore.connect then
    
    
    Dim recordSet As RecordSet
    recordSet = connettore.db.SQLSelect(query.ConvertEncoding(Encodings.UTF8))
    
    If connettore.db.Error Then
      MsgBox("DB Error: " + connettore.db.ErrorMessage)
    else 
      
      If recordSet <> Nil Then
        While Not recordSet.EOF
          
          atletaTmp.id = recordSet.Field("id").IntegerValue
          atletaTmp.nome = recordSet.Field("nome").StringValue
          atletaTmp.cognome = recordSet.Field("cognome").StringValue
          recordSet.MoveNext
        Wend
        
        recordSet.Close
      End If

Ma non carica il dato.

Premetto la medesima Query con lo stesso parametro in Ingresso funziona sul client di Mysql.

Qualcuno sa aiutarmi?

NomeCognome che encoding ha in origine?

Ciao domenico ho sempre avuto il problema di encoding con MYSQL
Ho risolto con poche difficolt :

Quando scrivo il record con databaserecord :
row.column(“codice”) = trim(self.txtcodice.text).UTF8return

[code]Public Function UTF8return(Extends testo As string) as string
dim risultato as string
risultato = testo.ConvertEncoding(Encodings.UTF8)
return risultato

End Function
[/code]

Quando scrivo il valore nel recordset :
rsitem.Field(“notedistinta”).UTF8Value = txtnotedistinta.text

Public Sub UTF8Value(Extends field As DatabaseField, Assigns value As String)
  field.StringValue = value.UTF8return
  
End Sub

Quando leggo il valore dal recordset
txtdeescrizione.Text = rsitem.field(“descrizione”).utfValue

Public Function utfValue(extends dbf as DatabaseField) as String
  dim s as String=dbf.StringValue
  if s.Encoding=nil then
    Return s.DefineEncoding(Encodings.UTF8)
  else
    Return s
  end if
End Function

E poi ovvio, come hai fatto tu, ci metto il comando per impartire a mysql il formato di encoding

 app.db.SQLExecute("SET NAMES utf8 COLLATE utf8_general_ci; SET CHARACTER SET utf8")

Cos funziona, non ho mai avuto problemi.
Anzi … dico palle, uno ne ho avuto con DynaPDF ma ho risolto…

// ragione sociale 2 call pdf.SetFont("Courier", 0, 8, true, pdf.kcpUnicode) call pdf.SetTextRect(74,38,160,6) call pdf.WriteFText(0,main.dtazienda.supragionesocale)

Con Postgre e Sqlite questi casini non succedono. E’ proprio un errore di MariaDB e Mysql

Ciao @Antonio Rinaldi

il sorgente di quel dato un file CSV

Grazie mille @Massimiliano Chiodi provo a fare come mi hai detto.

Si un po noiosa questa faccenda del MySql :smiley:
sto pensando di migrare al postgres :wink:

Dipende Domenico… Postgree mi sembre lento.
Fai conto che ho elaborato 1200 ddt di 3 pagine per emettere le fatture…
con Postgree il mac si addormenta… certo, ovvio, non era installato su di un server veloce.
Allo stesso modo per mysql scattante, per non gratis.

Prova ad impostare l’encoding nella lettura del file non a livello dei singoli elementi (tipo leggi la riga con l’encoding giusto e poi la dividi nei componenti)
A quel punto dovrebbe funzionare senza troppi problemi.

Quanto al problema di mySql con utf8, questo deriva dal fatto che per gli americani il fatto che non ha encoding la stringa letta non un problema (per la maggior parte delle volte).
Alla conferenza di Monaco ho sottolineato che questo per gli europei non vero in quanto per forza usiamo ormai utf-8.
Ho proposto quindi di rendere ufficiali le varie UTF8Value in modo da semplificare il nostro lavoro. Vedremo.

Quando due/tre anni fa Antonio ti avevo parlato del problema mi avevi assicurato che nel suo interno, se diversamente specificato, era tutto UTF8 e sono andato avanti mesi con i problemi di lettura / scrittura su mysql … Poi mi hai aiutato dopo qualche mese a scrivere UTF8Value indicandomi che non dovevo usare ‘string’ ma ‘field’ o qualcosa di simile per farlo funzionare come extension. Adesso per me normale utilizzare queste istruzioni, che tra l’altro utilizzo anche su Postgre e su Sqlite senza che diano fastidio.
L’avvento di una integrazione ufficiale mi fa solo che piacere. Grazie Antonio !

Oggi faccio una prova con la vostra soluzione (Massimiliano + Antonio).
Ammetto che fastidioso anche perch poi ti sembra di aver fatto le cose corrette ma manca sempre un qualcosa.
Probabile che la lettura del CSV causa questo incoveniente.

Stai attento a non aprire il file CSV con encoding utf8 altrimenti diventi matto :slight_smile:
Se i dati arrivano da IBM AS400 hai una codifica EBCDIC convertilo prima in ascii
Guarda qui : c’ la tabella dei caratteri unicode;
Avrai problemi con accenti e virgole, e sicuramente anche con gli apostrofi

Niente, non funziona.

Quando arrivo a leggere quella Query non restituisce niente. Sel a eseguo su phpMyAdmin funziona.

Penso che il problema sia quando leggo la riga dal CSV e la divido per estarre il dato che mi serve:

          Dim nomeAtletaCasa as String
          nomeAtletaCasa= rigaIncontro(i).Trim
          
          Dim pos as Integer
          pos = nomeAtletaCasa.InStr("nato a") - 1
          
          nomeAtletaCasa = nomeAtletaCasa.Mid(0, pos).DefineEncoding(Encodings.UTF8)

La Stringa nomeAtletaCasa il prbolema. Se non eseguo il MID tutto funziona. Ma quello mi serve.
Ho inserito il DefineEncoding ma niente da fare.
Ho utilizzato la funzione ConvertEncoding ma niente da fare.

Scoraggiato! haha

Domenico …
leggi tutta la riga…
tutta tutta
poi puoi usare
campo1 = nthfield(nomevariabileriga,“delimitatore”,numerodelcampo)
esempio campo1 = nthfield(nomevariabileriga,";",numerodelcampo)

poi pulisci le varie schifezze, ad esempio gli apici, gli spazi
usa campo1 = replaceall(campo1,chr(34),"") per sostituire gli apici
campo1 = replaceall(campo1,"’","") per sostituire il singolo apice … etc

quindi … usa nthfield per leggere una stringa con i dati separati da quello che vuoi

oppure usa split(nomevariabile,“delimitatore”) e infili tutto in un array…
la stessa cosa …
con il csv io ho visto diversi formati;
il delimitatore di campo , virgola o ; dipende quanto era ubriaco il programmatore quando ha letto il manuale;
il qualificatore di campo, di solito " doppio apice per le stringhe, oppure singolo apice, oppure anche senza; dipende sempre da quanto stato in osteria il programmatore.
la convenzione SAAA IBM riporta che CSV ( comma separated value ) deve avere delimitatore comma, quindi la virgola e il testo deve essere qualificato con gli apici, ma come ti ho scritto sempre un discorso di vecchia osteria
usa nthfield per usare i singoli campi.
se non conosci quanti campi sono, conta il numero di volte che il delimitatore c’ nella striga == INSTR (inizio, carattere da cercare) ti dice quante volte il carattere da cercare presente nella stringa.
il csv ha sempre nel suo interno un delimitatore.
anche il file separato con altro delimitatore, che alla fine non pi un CSV usa ad esempio il TAB
comunque o con SPLIT o con NTHFIELD riesci a fare lo stesso

Magari non sembra… ma anche io sono appena tornato dall’osteria…

Provato, ma niente. La query non restituisce niente come sempre.

Grazie dell’aiuto. Cercher una soluzione “alternativa”

Ho provato in tutti i modi, solo se cablo il dato nella query funziona.

Ora ho provato a convertire in codice ASCII ogni singolo carattere della stringa estratta dal CSV. Per poi riconvertirlo in Stringa partendo dal codice Ascii.

          dim ricerca as String
          dim y as Integer
          for y = 0 to datoFromCSV.Len
            Dim codAscii As Integer
            codAscii = Asc(Lowercase(datoFromCSV.Mid(y, 1))) 
            if codAscii > 0 then
              ricerca  =  "" + ricerca + Chr(codAscii)
            end if
          next

Ma anche cosi, dopo che inserisco il risultato nella query … non funziona.

ma che cappero di formato ?
non che hanno installato il server mysql con la codifica di default e ci scrivono in utf8 ? perch allora otterrai solo capperi e fagioli

So solo che il formato del MySQL sul server utf8_general_ci
La cosa curiosa e che su altre tabelle riesco a leggere con i dati letti da un altro CSV.

Dici che i dati sono stati inseriti non in UTF8?

Hai per caso un’altra spiegazione ?

Hai provato ad aprile il file con un HEX EDITOR per capire come codificato ?

io controllerei quel nomeAtletaCasa.Mid(0, pos)

dovresti partire da 1 con string

Dim query as String
query = “SELECT * FROM atleta WHERE upper(concat(cognome , ’ ’ , nome)) = '”
query = query + Uppercase(nomeCognome.Trim) + “’”

dim connettore as New Connettore
if connettore.connect then

Dim recordSet As RecordSet
recordSet = connettore.db.SQLSelect(query)

If connettore.db.Error Then
  MsgBox("DB Error: " + connettore.db.ErrorMessage)
else 
  
  If recordSet <> Nil Then
    While Not recordSet.EOF
      
      atletaTmp.id = recordSet.Field("id").IntegerValue
      atletaTmp.nome = recordSet.Field("nome").StringValue
      atletaTmp.cognome = recordSet.Field("cognome").StringValue
      recordSet.MoveNext
    Wend
    
    recordSet.Close
  End If