Italian [risolto] [solved] [b4j] e mariadb (mysql)

giannimaione

Well-Known Member
Licensed User
Longtime User
in un db mariadb (mysql) ho una view (vista), dove tra i vari campi da visualizzare c'è la seguente istruzione
B4X:
REPLACE(REPLACE(REPLACE(FORMAT(importo, 2), ".",  "p"), ",",  "."), "p",  ",") As netto
in pratica sql converte il valore del campo importo "FLOAT (9, 2)" dal formato 1234.56 in 1.234,56
il tutto funziona bene, ma installando il file jar del progetto presso il cliente (win10 64bit, stessa versione java, stessa versione mariadb),
va in crash e mi ritorna questo (uno stralcio del log):
B4X:
java.sql.SQLTransientConnectionException: (conn=54) Illegal mix of collations (utf8mb4_unicode_ci,COERCIBLE), (utf8mb4_general_ci,COERCIBLE), (utf8mb4_general_ci,COERCIBLE) for operation 'replace'
        at org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.createException(ExceptionFactory.java:79)
        at org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.create(ExceptionFactory.java:153)
.....
.....
....
Caused by: org.mariadb.jdbc.internal.util.exceptions.MariaDbSqlException: Illegal mix of collations (utf8mb4_unicode_ci,COERCIBLE), (utf8mb4_general_ci,COERCIBLE), (utf8mb4_general_ci,COERCIBLE) for operation 'replace'
        at org.mariadb.jdbc.internal.util.exceptions.MariaDbSqlException.of(MariaDbSqlException.java:34)
        at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.exceptionWithQuery(AbstractQueryProtocol.java:194)
        at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.exceptionWithQuery(AbstractQueryProtocol.java:177)
        at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.executeQuery(AbstractQueryProtocol.java:321)
        at org.mariadb.jdbc.ClientSidePreparedStatement.executeInternal(ClientSidePreparedStatement.java:220)
        ... 9 more
Caused by: java.sql.SQLException: Illegal mix of collations (utf8mb4_unicode_ci,COERCIBLE), (utf8mb4_general_ci,COERCIBLE), (utf8mb4_general_ci,COERCIBLE) for operation 'replace'

sembra che la causa sia da individuare nel "set" utf8.....bla....bla....
in rete ho trovato tanti forum con questo tipo di errore, e pur tentando con qualche modifica al db (tipo di "set") non ho risolto.


chiaramente se nella "view" del db tolgo le istruzione REPLACE, funziona
 

sirjo66

Well-Known Member
Licensed User
Longtime User
Di solito quando si estraggono dati da un database si mantiene il tipo di dato, cioè si fanno delle conversioni direttamente sulla query solo se necessario ed indispensabile.

Nel tuo caso mi sembra si tratti solo di una questione di visualizzazione, non di calcoli particolari che deve fare necessariamente il database.
Stai convertendo infatti un tipo di dati Float(9,2) in un tipo di dati String solamente per metterci i punti delle migliaia e la virgola.

Di solito invece si estrae dal database il tipo Float e poi in fase di visualizzazione si fa tutto quello che serve per farlo vedere nel formato che vogliamo.
Questo ti risolve un sacco di problemi soprattutto se devi ad esempio vendere il programma all'estero dove hanno un formato diverso, oppure se un domani vuoi fare delle modifiche che vanno a considerare il valore del campo "importo" (cosa che adesso non puoi fare perchè è un string) oppure perchè vuoi visualizzare la tabella mettendola in ordine di "importo" (cosa che ora non puoi fare perchè è string) eccetera eccetera eccetera...........

Dove devi visualizzare questo importo ??
Su di un TextEdit o su di una tabella ??

Sergio
 

giannimaione

Well-Known Member
Licensed User
Longtime User
ok, d'accordo su tutto; ma non riesco a capire il perché su due pc apparentemente "simili" con le stesse versioni java, db, ecc. riscontro il problema su uno solo (quello del cliente, che sfiga!)

il perché di quel REPLACE ?
ho una classe a cui "passo" un parametro contenente il nome di una tabella o di una view; questa classe visualizza in una tabella tutti i campi della table (l'utente decide quali campi visualizzare per ogni singola table); il tutto gestito "a pagine"
B4X:
select bla, bla, bla
limit ... ecc
@aeric mi suggerisce questo
eseguo delle verifiche e posto il risultato
 

sirjo66

Well-Known Member
Licensed User
Longtime User
1) non riesco a capire il perché su due pc apparentemente "simili" con le stesse versioni java, db, ecc. riscontro il problema su uno solo (quello del cliente, che sfiga!)

2) questa classe visualizza in una tabella tutti i campi della table

1) Perchè il PC del cliente avrà una configurazione diversa dal tuo, e vattelapesca a trovarlo.
io una volta sono diventato matto per poi scoprire che il cliente invece che avere configurato il separatore ore/minuti sui due punti, ce l'aveva sul punto, per cui gli orari invece che "10:20" venivano "10.20" e non riuscivo più a fare le trasformazioni

2) come dici tu la classe visualizza i campi, per cui devi modificare il codice della classe che quando va a visualizzare i campi Float imposta i separatori corretti
Fidati, ci perdi un paio di ore, ma poi non sai quante ore hai risparmiato, perchè come hai visto i problemi vengono fuori sempre dal cliente
 

sirjo66

Well-Known Member
Licensed User
Longtime User

Nei miei progetti in PHP quando devo lavorare con database MySQL, all'inizio del codice faccio sempre queste righe:
B4X:
mysql_connect($mysql_host,$mysql_user,$mysql_password);  // apro la connessione al server
mysql_select_db($mysql_database);  // mi collego al database corretto
mysql_query("SET CHARACTER SET utf8");  // setto per default UTF8

Potresti quindi provare ad aprire la connessione al database e fare subito la query che vedi nel codice sopra
 

giannimaione

Well-Known Member
Licensed User
Longtime User
pur modificando la stringa di connessione "?characterEncoding=utf8"
non funziona :mad:

nel mio pc il db ha la seguente configurazione/proprietà :
utf8_general_ci

mentre nel pc del cliente:
latin1_swedish_ci

inoltre sul pc del cliente, tra i vari "set" disponibili NON c'è utf8_general_ci :mad::mad::mad:

che faccio ? mi appendo al tram !?!?
 

LucaMs

Expert
Licensed User
Longtime User
che faccio ? mi appendo al tram !?!?
No, fai quello che ti ha suggerito @sirjo66:
Di solito quando si estraggono dati da un database si mantiene il tipo di dato, cioè si fanno delle conversioni direttamente sulla query solo se necessario ed indispensabile.

Nel tuo caso mi sembra si tratti solo di una questione di visualizzazione, non di calcoli particolari che deve fare necessariamente il database.
Stai convertendo infatti un tipo di dati Float(9,2) in un tipo di dati String solamente per metterci i punti delle migliaia e la virgola.

Di solito invece si estrae dal database il tipo Float e poi in fase di visualizzazione si fa tutto quello che serve per farlo vedere nel formato che vogliamo.
Questo ti risolve un sacco di problemi soprattutto se devi ad esempio vendere il programma all'estero dove hanno un formato diverso, oppure se un domani vuoi fare delle modifiche che vanno a considerare il valore del campo "importo" (cosa che adesso non puoi fare perchè è un string) oppure perchè vuoi visualizzare la tabella mettendola in ordine di "importo" (cosa che ora non puoi fare perchè è string) eccetera eccetera eccetera...........

Dove devi visualizzare questo importo ??
Su di un TextEdit o su di una tabella ??

Sergio
 
Top