Problemi di Encoding

Ciao a tutti.
Ho un problema di cui non capisco l’origine, e di conseguenza non so come risolvere.
Ho un progetto Xojo 2017r3 sviluppato in ambiente Windows 10 e che utilizza un database SQL Server Express tramite MSSQLServer plugin
Carico in un Listbox i record della tabella “A”: metto in debug il tutto e vedo che le variabili che imposta dai campi della tabella hanno encoding US-ASCII.
Non ne capisco molto di DefineEncoding, ConvertEncoding ecc., fatto sta che le lettere accentate, e tanti altri caratteri speciali sono visualizzati in un modo errato.
Faccio la stessa operazione sulla tabella “B”, e stavolta l’encoding Nil (e tutto funziona correttamente).

Le mie domande sono:
a) come mai due tabelle dello stesso Database hanno encoding diversi?
b) come si rimedia?

Utilizzando ODBC tutto funziona bene, perch entrambe le tabelle hanno encoding UTF-8.

Grazie di cuore a chi mi illuminer su questo problema.

Nedi

avevamo gi provato a risolvere una questione simile NEDI
Xojo al suo interno sempre utf8, mysql sappiamo che non digerisce utf8 con la codifica europea;
Mssql non lo utilizzo ma possiamo provare a litigarci un pochino…

Public Sub UTF8Value(Extends field As DatabaseField, Assigns value As String)
  field.StringValue = value.UTF8return
  
End Sub
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
Public Function UTF8return(Extends testo As string) as string
  dim risultato as string
  risultato = testo.ConvertEncoding(Encodings.UTF8)
  return risultato  
End Function

La prima funzione per modificare un record : esempio

rsrecord.edit
rsrecord.filed(“campo”).UTF8Value = “Quello che vuoi scrivere”
rsrecord.update

In pratica scrive il record con la codifica UTF8
La seconda ‘utfValue’ fa l’operazione contraria esempio
dim test as string
test = rsrecord.field(“campo”).utfValue

La terza la uso per le variabili oppure per scrivere databaserecord
dim testo as string = variabile.utf8return

dim rec as databaserecord
rec.column(“prova”) = stringa.utf8return

Prova a vedere se funziona…

Non uso preparedstatement sono allergico.

Ho cercato di approfondire la cosa (nei limiti delle mie conoscenze), e ho scoperto che le tabelle hanno Nil come encoding (almeno cos vedo guardando i vari campi del recordset contenente i dati).
Quello che cambia l’encoding delle variabili in cui vado ad appoggiare il contenuto dei campi del recordset.
Ecco quello che ho notato:

Dim wDescrElem As String = DW.Field("DescrElem").StringValue            --> Nil
Dim wDescrElem As String = DW.Field("DescrElem").StringValue.Trim       --> US-ASCII
Dim wAnno As String = DW.Field("DUT_AnnoDoc").IntegerValue.ToText       --> UTF-8 
Dim wData As String = DW.Field("DUT_DtaDoc").DateValue.ShortDate        --> UTF-8
wDataConsSQL = DW.Field("DUT_DtaConsConf").DateValue.SQLDate            --> US-ASCII
Dim wAnno As String = CStr(DW.Field("CT_AnnoNum").IntegerValue)         --> US-ASCII
Dim wAnno As String = Format(DW.Field("CT_AnnoNum").IntegerValue, "#")  --> UTF-8

Non l’ho verificato, ma direi che usando ODBC tutte le variabili hanno encoding UTF-8.

Hai provato con le tre funzioni che ti ho postato ?

No Max, non voglio metter mano all’intero progetto. Se non risolvo con il plugin utilizzo ODBC, con il quale tutto funziona perfettamente.
Grazie comunque per il suggerimento.

Potresti provare con ConvertEncoding, ovvero:

Dim wDescrElem As String = DW.Field("DescrElem").StringValue.ConvertEncoding(Encodings.WindowsANSI)

UTF e SQL Server un po’ complicato. A seconda della versione (e nel futuro probabilmente cambier ancora) devi operare diversamente e quindi la risposta non semplice di per se.

In ogni caso cerco di spiegare la tabella che hai postato:

Dim wDescrElem As String = DW.Field("DescrElem").StringValue            --> Nil

Questo quanto riporta il tuo “driver” nel collegamento al tuo db. Per identificare l’encoding corretto dovresti leggere un campo con dati definiti (contenenti lettere accentate e simboli particolari come ad esempio ) fare il break, notare che nil e provare a modificare l’encoding fino a identificare quello corretto (dal debugger fattibile)

Dim wDescrElem As String = DW.Field("DescrElem").StringValue.Trim       --> US-ASCII

Qui hai operato sulla stringa (Trim) per cui probabilmente il risultato passa da nil ad ASCII, ma non garantisce che i caratteri, ovviamente, siano corretti.

Dim wAnno As String = DW.Field("DUT_AnnoDoc").IntegerValue.ToText       --> UTF-8

Text un tipo con encoding per cui il minimo accettabile per gli interi UTF-8 (nella conversione di numeri non hai caratteri speciali)

Dim wData As String = DW.Field("DUT_DtaDoc").DateValue.ShortDate --> UTF-8 wDataConsSQL = DW.Field("DUT_DtaConsConf").DateValue.SQLDate --> US-ASCII Dim wAnno As String = CStr(DW.Field("CT_AnnoNum").IntegerValue) --> US-ASCII
ShortDate una stringa costruita da Xojo per cui di default ha encoding UTF-8.
SQLDate lo stesso una stringa di Xojo ma essendo composta solo di numeri ha encoding ASCII (basta quello)
Lo stesso per CStr o Str sui numeri

Dim wAnno As String = Format(DW.Field("CT_AnnoNum").IntegerValue, "#")  --> UTF-8

Format, diversamente da Str potrebbe prendere un formato locale con caratteri esterni a ASCII e quindi UTF-8. Ma di nuovo Xojo che interviene su un numero.

Il problema quindi solo nella conversione del primo caso.

Grazie Antonio!

La tabella che ho postato contiene informazioni che ho dedotto mettendo il programma in break ed osservando le variabili.
In quel caso stavo utilizzando il Plugin MSSQLServer.
La stessa operazione fatta utilizzando ODBC riporta tutti UTF-8, tranne che con SqlDate e Cstr.
Quindi sono arrivato alla conclusione che meglio utilizzare ODBCDatabase.
Sei d’accordo?