View Full Version : [C#] MySqlParameter e tabelle case sensitive
tomminno
01-07-2009, 22:24
Riscontro un problema nell'utilizzo dei MySqlParameter con un MySql su Linux dove qualche disgraziato ha creato le tabelle con i nomi tutti in maiuscolo.
In sostanza quando vado ad eseguire la query ottengo che la tabella non esiste e nell'errore il nome della tabella riportato è tutto minuscolo.
C'è qualche opzione lato codice che consente di specificare di non alterare il testo della query, quando si usano i parametri?
Non ho accesso alla macchina database nè ho modo di modificarne le impostazioni o alterare le tabelle.
Al momento ho messo una pezza componendo la query a mano, ma chiaramente la soluzione è decisamente inadeguata.
L'essere case sensitive e' uno dei parametri di MySql.
Per aderire allo standard SQL che vuole i nomi di campi/tabelle/etc. non case-sensitive occorrerebbe agire sull'istanza e cambiare il valore anche solo di tale parametro (del quale non mi ricordo il nome, e che spero di non ricordare proprio piu', per non occupare inutilmente la MIA memoria)
Pero' non ho capito perche' impostare tutto maiuscolo i nomi dei campi dei vari MySqlParameter sia una soluzione inadeguata.
Stai usando qualche automatismo nella composizione delle query?
tomminno
02-07-2009, 12:24
L'essere case sensitive e' uno dei parametri di MySql.
Per aderire allo standard SQL che vuole i nomi di campi/tabelle/etc. non case-sensitive occorrerebbe agire sull'istanza e cambiare il valore anche solo di tale parametro (del quale non mi ricordo il nome, e che spero di non ricordare proprio piu', per non occupare inutilmente la MIA memoria)
Si c'è un'opzione ma appunto esegue il tolower e quindi non matcherà mai una tabella con caratteri maiuscoli. Infatti è indicato sulle guide di mysql di creare solo tabelle con caratteri minuscoli.
Pero' non ho capito perche' impostare tutto maiuscolo i nomi dei campi dei vari MySqlParameter sia una soluzione inadeguata.
Il problema non sono i nomi dei parametri è che sembra venga eseguito da non so chi un tolower sulla query cioè io scrivo:
string query = "update TABELLA set campo1=@campo1 where pk=@PK";
command.Parameters.Add(new MySqlParameter("@campo1", 111));
command.Parameters.Add(new MySqlParameter("@PK", 222));
e ottengo l'errore :
"Table 'database.tabella' doesn't exist"
il fatto che mi segnali il nome della tabella minuscolo e dica che non esiste mi fa pensare che da qualche parte qualcuno stia facendo il tolower della query, tolower che non viene eseguito se non uso i MySqlParameter, visto che l'update liscio funziona.
Stai usando qualche automatismo nella composizione delle query?
Nessun automatismo se non un Append di StringBuilder, ma l'errore lo dà anche se scrivo la query come stringa unica.
RaouL_BennetH
02-07-2009, 12:50
Ciao :)
Se invece provi a fare:
string tableName = "tabella";
string query = "update " + tableName.ToUpper() + " set campo1=@campo1 where pk=@PK";
command.Parameters.Add(new MySqlParameter("@campo1", 111));
command.Parameters.Add(new MySqlParameter("@PK", 222));
Funziona?
magari per evitare di dover ogni volta fare questo per le tabelle, potresti fare
public string getTableName(string tableName)
{
return tableName.ToUpper();
}
Kralizek
02-07-2009, 13:15
forse mi sbaglio ma mi ricordo di aver letto che mysql é case sensitive su linux ma non su windows.
onestamente non ci ho mai provato...
cdimauro
02-07-2009, 13:33
E' così. E questo perché:
- quei genii che hanno creato Unix hanno realizzato filesystem case sensitive (a uso e consumo delle macchine e... dei programmatori, anziché degli esseri umani);
- gli ipergenii di MySQL hanno deciso di mappare le tabelle su filesystem (in appositi file con lo stesso nome).
Per cui MySQL si comporta in maniera standard (SQLxyz) su s.o. che hanno filesystem case insensitive (Windows, AmigaOS, ecc.), e non standard su quelli case sensitive (Unix & co).
Ovviamente "per coerenza", tutti gli altri tipi di identificatori (nomi dei campi, delle stored procedure, ecc. ecc.) sono... case insensitive, a prescindere dal sensibilità al case del filesystem.
tomminno
02-07-2009, 22:29
E' così.
Si lo so, non è il massimo della vita, speravo solo che qualcuno si fosse già imbattuto in questo problema. Non riesco a trovare niente a riguardo in giro.
Ho il sospetto che il problema però possa essere nel MySql.Data, domani faccio una prova in C++ e vedo cosa ottengo.
E questo perché:
- quei genii che hanno creato Unix hanno realizzato filesystem case sensitive (a uso e consumo delle macchine e... dei programmatori, anziché degli esseri umani);
Beh anche quei genii della Microsoft hanno fatto NTFS case sensitive ;)
Mai provato l'ebbrezza del case sensitive sotto Windows?
E' un ottimo modo per nascondere i file, basta cambiare il case e magicamente vedi tutto un altro file, con SVN capita di ritrovarsi con 2 (o più) file diversi fisicamente presenti sul disco ma Windows ovviamente te ne mostra solo 1 dei 2, se però cambi il case appare il file giusto, non ho ancora capito come possa accadere, ma l'ho sperimentato più volte.
- gli ipergenii di MySQL hanno deciso di mappare le tabelle su filesystem (in appositi file con lo stesso nome).
eh già loro si che sono stati veri genii :doh:
cdimauro
03-07-2009, 05:31
Si lo so, non è il massimo della vita, speravo solo che qualcuno si fosse già imbattuto in questo problema. Non riesco a trovare niente a riguardo in giro.
Ho il sospetto che il problema però possa essere nel MySql.Data, domani faccio una prova in C++ e vedo cosa ottengo.
E' un problema che puoi risolvere o cambiando il codice (ma vai a trovare il punto in cui è fallato) oppure facendo diventare il filesystem di Linux case insensitive.
Beh anche quei genii della Microsoft hanno fatto NTFS case sensitive ;)
NTFS è case insensitive. Ma hanno aggiunto anche la possibilità, nella definizione del filesystem, di renderlo case sensitive.
Quindi puoi realizzare applicazioni / driver che lo implementano case sensitive, ma non mi risulta che sia possibile farlo funzionare in questo modo in Windows.
Mai provato l'ebbrezza del case sensitive sotto Windows?
No. Come lo imposti case sensitive?
E' un ottimo modo per nascondere i file, basta cambiare il case e magicamente vedi tutto un altro file, con SVN capita di ritrovarsi con 2 (o più) file diversi fisicamente presenti sul disco ma Windows ovviamente te ne mostra solo 1 dei 2, se però cambi il case appare il file giusto, non ho ancora capito come possa accadere, ma l'ho sperimentato più volte.
Non ho capito bene. Il repository è su un filesystem case sensitive (su Linux, immagino), e tu provi a giocare col case dei file in locale?
eh già loro si che sono stati veri genii :doh:
MySQL è un engine SQL tirato sù per "pezze", aggiungendo roba al momento del bisogno, senza una visione precisa di come realizzarlo, e con grossolani errori progettuali (quello del case è soltanto uno dei tanti).
tomminno
03-07-2009, 12:15
E' un problema che puoi risolvere o cambiando il codice (ma vai a trovare il punto in cui è fallato) oppure facendo diventare il filesystem di Linux case insensitive.
Il problema di fondo è che se uso i pararmetri sono più al riparo da sql injection, nel caso di query composta concatenando stringhe, beh bisonga fare 10000 controlli per ogni stringa da concatenare.
NTFS è case insensitive. Ma hanno aggiunto anche la possibilità, nella definizione del filesystem, di renderlo case sensitive.
Veramente NTFS è case senstive, è Windows che è case insensitive.
Quindi puoi realizzare applicazioni / driver che lo implementano case sensitive, ma non mi risulta che sia possibile farlo funzionare in questo modo in Windows.
Forse è sfuggito il punto del problema, che è l'esecuzione di qualche parte del codice non mio (MySql.Data o il server MySql) di un tolower sulla query che quindi non matcha più una tabella tutta maiuscola che sta una macchina Linux.
No. Come lo imposti case sensitive?
Non lo imposto però prelevando i sorgenti da una macchina linux capita (qualche volta eh) che abbia riscontrato l'esistenza fisica su HD di più file con il nome differente solo nel case.
Non ho capito bene. Il repository è su un filesystem case sensitive (su Linux, immagino), e tu provi a giocare col case dei file in locale?
Si, non è che capita giocando è che ogni tanto qualche collega rinomina un file perchè gli piace Web.config piuttosto che web.config e ogni tanto capita (non so per quale strana combinazione astrale) di accorgersi che sul file system locale ci sono effettivamente entrambi i file, infatti rinominando da web.config a Web.config e viceversa si vedono i dati di un file piuttosto che dell'altro.
Credo che la colpa sia tutta di TortoiseSVN, però mi sono sempre chiesto come ci riesca.
banryu79
03-07-2009, 12:35
Si, non è che capita giocando è che ogni tanto qualche collega rinomina un file perchè gli piace Web.config piuttosto che web.config e ogni tanto capita (non so per quale strana combinazione astrale) di accorgersi che sul file system locale ci sono effettivamente entrambi i file, infatti rinominando da web.config a Web.config e viceversa si vedono i dati di un file piuttosto che dell'altro.
Credo che la colpa sia tutta di TortoiseSVN, però mi sono sempre chiesto come ci riesca.
Ah, della serie: "Non è un bug: è una feature!" :asd:
tomminno
03-07-2009, 12:48
Ah, della serie: "Non è un bug: è una feature!" :asd:
Non sono poi del tutto convinto che possa essere definito un bug di Tortoise, non credo proprio utilizzino un driver per andare a scrivere direttamente su NTFS, ergo ci deve essere qualcosa che non va su Windows...
cdimauro
04-07-2009, 08:02
Il problema di fondo è che se uso i pararmetri sono più al riparo da sql injection, nel caso di query composta concatenando stringhe, beh bisonga fare 10000 controlli per ogni stringa da concatenare.
Già. Infatti è la mia via preferita per passare parametri a una query. Meglio ancora sarà passare all'uso delle stored procedure, appena ne avrò la possibilità.
Veramente NTFS è case senstive, è Windows che è case insensitive.
Da qui (http://en.wikipedia.org/wiki/NTFS):
Allowed characters in filenames
In Posix namespace, any UTF-16 code unit (case sensitive) except U+0000 (NUL) and / (slash).
In Win32 namespace, any UTF-16 code unit (case insensitive) except U+0000 (NUL) / (slash) \ (backslash) : (colon) * (asterisk) ? (Question mark) " (quote) < (less than) > (greater than) and | (pipe) [3]
Forse è sfuggito il punto del problema, che è l'esecuzione di qualche parte del codice non mio (MySql.Data o il server MySql) di un tolower sulla query che quindi non matcha più una tabella tutta maiuscola che sta una macchina Linux.
Immaginavo fosse qualcosa del genere. C'è Linux di mezzo.
Comunque se il codice non è tuo e/o non lo puoi modificare, ti tocca scriverti la query da te. Non credo che ti facciano cambiare il case del filesystem della macchina Linux in cui sta il db. :p
Non lo imposto però prelevando i sorgenti da una macchina linux capita (qualche volta eh) che abbia riscontrato l'esistenza fisica su HD di più file con il nome differente solo nel case.
Si, non è che capita giocando è che ogni tanto qualche collega rinomina un file perchè gli piace Web.config piuttosto che web.config e ogni tanto capita (non so per quale strana combinazione astrale) di accorgersi che sul file system locale ci sono effettivamente entrambi i file, infatti rinominando da web.config a Web.config e viceversa si vedono i dati di un file piuttosto che dell'altro.
Credo che la colpa sia tutta di TortoiseSVN, però mi sono sempre chiesto come ci riesca.
Me lo chiedo anch'io, perché su Windows non possono esistere due file che differiscano esclusivamente per il case.
Non vorrei che TortoiseSVN facesse uso di qualche carattere speciale fra quelli user-defined che si possono utilizzare con Unicode, per differenziare i file.
NTFS supporta lo Unicode, quindi è possibile. Tra l'altro, a naso, non dovrebbero essere "stampabili" questi caratteri, per cui si spiegherebbe tutto.
tomminno
04-07-2009, 10:09
Già. Infatti è la mia via preferita per passare parametri a una query. Meglio ancora sarà passare all'uso delle stored procedure, appena ne avrò la possibilità.
Da qui (http://en.wikipedia.org/wiki/NTFS):
Allowed characters in filenames
In Posix namespace, any UTF-16 code unit (case sensitive) except U+0000 (NUL) and / (slash).
In Win32 namespace, any UTF-16 code unit (case insensitive) except U+0000 (NUL) / (slash) \ (backslash) : (colon) * (asterisk) ? (Question mark) " (quote) < (less than) > (greater than) and | (pipe) [3]
Qui (http://support.microsoft.com/kb/100625) affermano proprio che NTFS è case sensitive, mentre non lo è Windows:
As part of the requirements for POSIX compliance, the Windows NT File System (NTFS) provides a case-sensitive file and directory naming convention. Even though NTFS and the POSIX subsystem each handle case-sensitivity well, 16-bit Windows-based, MS-DOS-based, OS/2-based, and Win32-based applications do not.
Credo che la fonte sia più affidabile di wikipedia.
cdimauro
04-07-2009, 11:54
Non mi sembrano ci siano differenze e, tra l'altro, non è un problema di Windows, ma di subsystem (http://www.appuntidigitali.it/3006/i-subsystem-di-windows-fra-retrocompatibilita-ed-evoluzione/).
POSIX richiede e accede a NTFS in modalità case sensitive.
Tutti gli altri subsystem operano in modalità case insensitive.
Per la cronaca: il plurale di genio è geni !!! :stordita:
cdimauro
05-07-2009, 20:21
Preferisco continuare col vecchio meccanismo della replicazione delle i. Non mi piace l'uso attuale, che prevede il troncamento della seconda.
gene -> geni;
genio -> genii.
Io sono abituato così, e davanti a "geni" so già di quale parole è il plurale.
Tra l'altro anche parlando, si usa sempre questo meccanismo, perché la tendenza rimane quella di allungare la i, e non di pronunciarla in maniera secca e breve (come dovrebbe essere se si troncasse sempre la seconda i).
Certe "riforme" non le accetterò mai: mi sembrano insensate!
Kralizek
05-07-2009, 22:41
sarà dovuto alla cadenza napoletano, ma io dico "geni" non "genii"
eg: "quei ragazzi sono dei geni"
Anche io lo dico senza doppia "i", quindi diciamo che mi viene naturale ;)
RaouL_BennetH
07-07-2009, 09:59
Ciao tomminno.
Se non da codice dell'applicazione, hai modo di controllare come sta settato:
lower_case_table_names
in /etc/mysql/my.cnf ?
Per renderlo case insensitive, io ho impostato il valore ad 1.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.