MySQL Select mit Umlauten fehlerhaft...
SebastianJu
- datenbank
0 Vinzenz Mai0 dedlfix0 SebastianJu0 SebastianJu0 dedlfix
0 SebastianJu
Hallo,
kann mir jemand mit diesem Phänomen weiterhelfen?
Ich habe eine MySQL-Datenbank Version: 5.0.41-community-nt
Darauf eine Datenbank mit collation: latin1_german1_ci
Alle Tabellenspalten und Tabellen haben auch diese collation.
Unter Anderem gibt es eine Tabelle mit den Feldern uid (int) und keyword (varchar 100). Darin werden nun Keywords gespeichert. Dabei ist mir aufgefallen dass manche Keywords nicht gespeichert werden. Beispielsweise die zwei Keywords:
cheats fur pc
cheats für pc
Das erste ist ein Typo der halt auch so gespeichert werden soll. Das Problem ist dass nur das erste Keywort gespeichert wird. Wenn beim zweiten Keywort angekommen ist dann wird ein select ausgeführt mit "where keyword = 'cheats für pc'". Dabei wird aber als Ergebnis der Datensatz von "cheats fur pc" zurückgeliefert. Das ist natürlich so nicht richtig.
Wie kann ich dass denn lösen?
Grüße!
Sebastian
Hallo,
Ich habe eine MySQL-Datenbank Version: 5.0.41-community-nt
Bei mir 5.0.51-community-nt ...
Darauf eine Datenbank mit collation: latin1_german1_ci
Alle Tabellenspalten und Tabellen haben auch diese collation.
Dabei ist mir aufgefallen dass manche Keywords nicht gespeichert werden. Beispielsweise die zwei Keywords:
cheats fur pc
cheats für pc
Wenn beim zweiten Keywort angekommen ist dann wird ein select ausgeführt mit "where keyword = 'cheats für pc'". Dabei wird aber als Ergebnis der Datensatz von "cheats fur pc" zurückgeliefert. Das ist natürlich so nicht richtig.
Dieses Verhalten kann ich nicht nachvollziehen. Ich kann problemlos beide Werte speichern und gezielt über eine Abfrage auslesen. Die WHERE-Klausel arbeitet erwartungsgemäß. Mit welchem Client setzt Du Deine Abfrage ab?
Freundliche Grüße
Vinzenz
Ich benutze Xampp 1.6.2 portabel installiert. Verstehe ich nicht dass es bei dir klappt... Ich versuche das ganze jetzt mal komplett als SQL-Anweisungen dazustellen. Vielleicht bringt das was...
Grüße!
Sebastian
Also, wenn ich die Tabellen lösche mit:
delete FROM
tab_keywords;
und dann diese SQL-Anweisungen ausgeführt werden:
SELECT * FROM tab_keywords as t1 where t1.keyword = 'Cheats fur PC'
insert into tab_keywords (keyword) values('Cheats fur PC')
uid=2302
SELECT * FROM tab_keywords as t1 where t1.keyword = 'Cheats für PC'
uid=2302
dann wie man sieht passiert das was nicht passieren sollte...
Wenn ich noch einmal lösche und direkt in phpmyadmin diese beiden zeilen ausführe dann erhalte ich ebenso den falschen Datensatz:
insert into tab_keywords (keyword) values('Cheats fur PC')
SELECT * FROM tab_keywords as t1 where t1.keyword = 'Cheats für PC'
Wie gesagt ist mir dieses Verhalten bisher nicht begegnet...
Grüße!
Sebastian
Hallo,
delete FROM
tab_keywords;
das CREATE-TABLE-Statement wäre interessant zu wissen. (SHOW CREATE TABLE tab_keywords)
SELECT * FROM tab_keywords as t1 where t1.keyword = 'Cheats fur PC'
insert into tab_keywords (keyword) values('Cheats fur PC')
uid=2302
versteh' ich nicht, gibt Syntaxfehler.
SELECT * FROM tab_keywords as t1 where t1.keyword = 'Cheats für PC'
uid=2302
> dann wie man sieht passiert das was nicht passieren sollte...
ich sehe nichts davon.
Folgendes funktioniert bei mir reproduzierbar und völlig erwartungsgemäß mit der phpMyAdmin-Einstellung
Zeichensatz / Kollation der MySQL-Verbindung: latin1\_german1\_ci
Erstelle die Tabelle:
~~~sql
CREATE TABLE `tab_keywords` (
`uid` INT NOT NULL AUTO_INCREMENT ,
`keyword` VARCHAR( 100 ) CHARACTER SET latin1 COLLATE latin1_german1_ci NULL ,
PRIMARY KEY ( `uid` )
) ENGINE = MYISAM CHARACTER SET latin1 COLLATE latin1_german1_ci
Füge zwei Datensätze ein:
INSERT INTO
tab_keywords (
uid,
keyword
)
VALUES
(NULL, 'Cheats fur PC'),
(NULL, 'Cheats für PC')
2 Zeile(n) eingefügt.
ID der eingefügten Zeile: 2 ( die Abfrage dauerte 0.1220 sek. )
Frage den Inhalt ab:
SELECT
uid,
keyword
FROM
tab_keywords
uid | keyword
----+-----------------
1 | Cheats fur PC
2 | Cheats für PC
Selektiere spezielles Keyword:
SELECT
uid,
keyword
FROM
tab_keywords
WHERE
keyword = 'Cheats fur PC'
uid | keyword
----+-----------------
1 | Cheats fur PC
Selektiere anderes spezielles Keyword:
SELECT
uid,
keyword
FROM
tab_keywords
WHERE
keyword = 'Cheats für PC'
uid | keyword
----+-----------------
2 | Cheats für PC
Du machst irgendetwas falsch!
Freundliche Grüße
Vinzenz
Ich habe jetzt folgenden Code ausgeführt:
CREATE TABLE `tab_keywords2` (
`uid` INT NOT NULL AUTO_INCREMENT ,
`keyword` VARCHAR( 100 ) CHARACTER SET latin1 COLLATE latin1_german1_ci NULL ,
PRIMARY KEY ( `uid` )
) ENGINE = MYISAM CHARACTER SET latin1 COLLATE latin1_german1_ci;
INSERT INTO
tab_keywords2 (
uid,
keyword
)
VALUES
(NULL, 'Cheats fur PC'),
(NULL, 'Cheats für PC');
SELECT
uid,
keyword
FROM
tab_keywords2;
Ergebnis:
1 Cheats fur PC
2 Cheats für PC
Dann:
SELECT
uid,
keyword
FROM
tab_keywords2
WHERE
keyword = 'Cheats fur PC';
mit Ergebnis:
1 Cheats fur PC
2 Cheats für PC
und:
SELECT
uid,
keyword
FROM
tab_keywords2
WHERE
keyword = 'Cheats für PC';
mit Ergebnis:
1 Cheats fur PC
2 Cheats für PC
Er findet also immer alles...
Woran könnte es denn sonst noch liegen? An irgendwelchen Datenbankeigenschaften? Auf der "home-Seite" gibt es einen Eintrag "Zeichensatz / Kollation der MySQL-Verbindung:" der steht auf utf8_unicode_ci. Ich habe den mal testweise auf german gesetzt aber das Ergebnis ist trotzdem nicht anders.
Darüber steht noch "MySQL-Zeichensatz: UTF-8 Unicode (utf8)" aber das kann ich offenbar nicht einstellen und auf Änderung testen.
Grüße!
Sebastian
echo $begrüßung;
Darauf eine Datenbank mit collation: latin1_german1_ci
Die Kollation des einzelnen Feldes ist letzlich relevant, aber die sind ja bei dir gleich eingestellt.
cheats fur pc
cheats für pc
Dass beides als gleich angesehen wird liegt an den Regeln der Kollation german1. Da ist eben definiert, dass sich bei Sortierungen uend Vergleichen ein ü wie ein u benimmt. Wenn du einen haargenauen Vergleich haben möchtest, nimm den BINARY-Operator dazu. Du kannst aber auch die Kollation auf *_bin umstellen, also latin1_bin in deinem Fall, dann wird auch zeichengenau verglichen.
echo "$verabschiedung $name";
Hm. Wieso funktioniert es dann bei Vinzenz?
Jedenfalls habe ich jetzt mal:
SELECT
uid,
binary keyword
FROM
tab_keywords2
WHERE
keyword = 'Cheats für PC'
und
SELECT
uid,
binary keyword
FROM
tab_keywords2
WHERE
binary keyword = 'Cheats für PC'
probiert.
Beim ersten wird geschrieben dass es ein Ergebnis gibt angeblich. "Zeige Datensätze 0 - 0 (1 insgesamt, die Abfrage dauerte 0.0011 sek.)". Aber angezeigt wird:
1 Cheats fur PC
2 Cheats f�r PC
Also beim zweiten Datensatz dieses falsche Zeichen.
Und bei der zweiten Abfrage kommt kein Datensatz zurück.
Grüße!
Sebastian
Ich habe mir deine verlinkte Seite noch mal durchgelesen und auch diese hier:
http://dev.mysql.com/doc/refman/5.1/en/charset-collation-effect.html
Nur erkenne ich immer noch keine Möglichkeit wie ich es hinbekomme dass a ae und ä auch als unterschiedlich angesehen werden...
Grüße!
Sebastian
echo $begrüßung;
Hm. Wieso funktioniert es dann bei Vinzenz?
Ich weiß nicht, was Vinzenz (falsch) macht, bei mir verhält sich sein Beispiel so wie es soll: u wird wie ü behandelt. Ich bekomme immer beide Datensätze. Das ist für german1 so definiert, also verhält sich mein MySQL definitionsgemäß.
Beim ersten wird geschrieben dass es ein Ergebnis gibt angeblich. "Zeige Datensätze 0 - 0 (1 insgesamt, die Abfrage dauerte 0.0011 sek.)". Aber angezeigt wird:
Kann ich nicht nachvollziehen, bei mir läuft alles so wie es soll. Allerdings musste ich auf der Startseite vom phpMyAdmin die Kodierung der Verbindung auf Latin1 umstellen, sonst hat der PMA die Query UTF8-kodiert gesendet und ein UTF-8-ü ist logischerweise nicht binärkompatibel zu einem Latin1-ü.
2 Cheats f�r PC
Also beim zweiten Datensatz dieses falsche Zeichen.
Bei mir nicht. Sieht aber danach aus, als ob jemand UTF-8 erwartet und Latin1 geschickt bekommt. Du hast irgendwo anders noch was nicht richtig gemacht. Vielleicht hantierst du mit einem PHP-Script, bei dem du vergessen hast, die gewünschte Kodierung nach dem Verbindungsaufbau auszuhandeln.
echo "$verabschiedung $name";
Ich glaube ich habe jetzt die Lösung. Statt varchar(100) benutze ich jetzt varbinary(100). Und nun kann ich in dieses uniquefeld die drei Versionen einbauen ohne Fehlermeldung:
'cheats fur pc'
'cheats für pc'
'cheats fuer pc'
Außerdem kann ich nun selects auf alle drei Versionen fahren und es werden jeweils immer die richtigen erkannt.
Grüße!
Sebastian