Problem mit Umlauten und Collations
Klaus
- datenbank
Hallo,
ich habe zwei Datenbanken, bei der die Kollation der einen Datenbank komplett auf utf8_general_ci (Tabelle und Felder) und die andere DB komplett auf latin1_general_ci eingestellt ist.
Nun habe ich in der ersten DB eine View erstellt, die Informationen aus der 2. DB zur Verfügung stellt.
create or replace view v_imported_users as
SELECT a.idnr as UserID,
a.loginname as UserName,
a.passwort as Password,
convert(b.name using utf8) collate utf8_general_ci as Name,
convert(b.vorname using utf8) collate utf8_general_ci as Surname,
b.email as email,
1 AS group_id, 'nophoto.jpg' as user_photo
FROM DB2.logins as a left join DB2.employees as b on a.loginname = b.pnr
where b.sichtbar <> 'N' AND b.kst <> ''
Dennoch werden auf der Seite die Umlaute von nur dieser View nicht korrekt angezeigt. Das typische Symbol mit dem Fragezeichen in der Raute wird angezeigt.
z.B.
B�rbel K�nig
Die Kodierung der HTML-Seite ist auch UTF8.
Habe ich eine Chance, die View anzupassen, sodass auch die Umlaute korrekt dargestellt werden?
Oder ist die einzige Möglichkeit, die Kollation der 2. DB auch auf UTF8 zu wechseln? (Ist das eigentlich unproblematisch für den Inhalt, wenn ich per Script die gesamte DB mit allen Tabellen und deren Felder auf UTF8 ändere?)
Hallo
Habe ich eine Chance, die View anzupassen, sodass auch die Umlaute korrekt dargestellt werden?
Ja. Die Kollation gibt an, nach welchen Relgeln die Sortierung von Abfrageergebnissen erfolgen soll (ORDER BY surname ASC
). Das hat aber nichts mit der Ausgabe der Ergebnisse zu tun. Um dort eine bestimmte Kodierung sicherzustellen, muss für die Datenbankverbindung genau diese Kodierung verbindlich festgelegt werden. Bei MySQL geht das für UTF-8 z.B. mit SET NAMES "utf-8"
. Andere Datenbanksysteme werden ähnliche Möglichkeiten bieten.
Tschö, Auge
Hallo Auge,
Ja. Die Kollation gibt an, nach welchen Relgeln die Sortierung von Abfrageergebnissen erfolgen soll (
ORDER BY surname ASC
). Das hat aber nichts mit der Ausgabe der Ergebnisse zu tun. Um dort eine bestimmte Kodierung sicherzustellen, muss für die Datenbankverbindung genau diese Kodierung verbindlich festgelegt werden. Bei MySQL geht das für UTF-8 z.B. mitSET NAMES "utf-8"
. Andere Datenbanksysteme werden ähnliche Möglichkeiten bieten.
Sorry, wenn ich das nicht gleich verstehe... Hätte ich vor dem Erstellen der View ein "set names" davor setzen müssen oder muss ich bei der Verwendung der View vorher ein "set names" setzen?
(meine DB ist MySQL)
Tach!
Sorry, wenn ich das nicht gleich verstehe... Hätte ich vor dem Erstellen der View ein "set names" davor setzen müssen oder muss ich bei der Verwendung der View vorher ein "set names" setzen?
Du musst (solltest) bei jedem Verbindungsaufbau die zu verwendende Kodierung angeben. So wie du mit jemandem aushandeln muss, in welcher Sprache ihr euch unterhalten wollt. Sonst gilt ein Defaultwert, der zufällig gleich sein kann oder auch nicht. Jeder Teilnehmer hat dabei die Gedanken in seinem Kopf in der Muttersprache abgelegt und muss sie zum Kommunizieren gegebenenfalls umkodieren.
dedlfix.
Hello Klaus,
Ja. Die Kollation gibt an, nach welchen Relgeln die Sortierung von Abfrageergebnissen erfolgen soll (
ORDER BY surname ASC
). Das hat aber nichts mit der Ausgabe der Ergebnisse zu tun. Um dort eine bestimmte Kodierung sicherzustellen, muss für die Datenbankverbindung genau diese Kodierung verbindlich festgelegt werden. Bei MySQL geht das für UTF-8 z.B. mitSET NAMES "utf-8"
. Andere Datenbanksysteme werden ähnliche Möglichkeiten bieten.Sorry, wenn ich das nicht gleich verstehe... Hätte ich vor dem Erstellen der View ein "set names" davor setzen müssen oder muss ich bei der Verwendung der View vorher ein "set names" setzen?
Du hast doch vermutlich drei bis vier beteiligte, oder?
DB-1 DB-2
\ /
\ /
\ /
\________ Script _____/
|
|
|
|
Ausgabe
Die verarbeitende Instanz (Script) muss nun zwei Datenbankverbindungen eröffnen, bei denen in beiden die passende Codierung für die Datenbank eingestellt werden muss
Wenn es ein PHP-Script ist, geht das z.B. so:
if (!mysqli_set_charset($con, 'utf8')) return false;
Das bedeutet dann aber auch, dass das Script mit zwei unterschiedlichen Codierungen zurecht kommen muss.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallo
Wenn es ein PHP-Script ist, geht das z.B. so:
if (!mysqli_set_charset($con, 'utf8')) return false;
Das bedeutet dann aber auch, dass das Script mit zwei unterschiedlichen Codierungen zurecht kommen muss.
Wieso sollte s? Das *eine* Skript erzeugt *eine* Ausgabe mit *einer* Kodierung aus *zwei* Quellen. Wo sollte wohl die Vereinheitlichung stattfinden, wenn nicht bei der Verbindung zu den zwei Quellen? Somit bleibt (zum Glück) nur eine Kodierung, mit der man im Skript umgehen muss, übrig.
Tschö, Auge
Hello,
Wenn es ein PHP-Script ist, geht das z.B. so:
if (!mysqli_set_charset($con, 'utf8')) return false;
Das bedeutet dann aber auch, dass das Script mit zwei unterschiedlichen Codierungen zurecht kommen muss.
Wieso sollte s?
Du plädierst also auch für zwei Connections mit zwei Codierungen. Eine Connection muss dann eben umrechnen. Klappt das immer?
Das *eine* Skript erzeugt *eine* Ausgabe mit *einer* Kodierung aus *zwei* Quellen. Wo sollte wohl die Vereinheitlichung stattfinden, wenn nicht bei der Verbindung zu den zwei Quellen? Somit bleibt (zum Glück) nur eine Kodierung, mit der man im Skript umgehen muss, übrig.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallo
Das bedeutet dann aber auch, dass das Script mit zwei unterschiedlichen Codierungen zurecht kommen muss.
Wieso sollte s?
Du plädierst also auch für zwei Connections mit zwei Codierungen. Eine Connection muss dann eben umrechnen. Klappt das immer?
Nein, ich plädiere für zwei Verbindungen (die braucht Klaus eh, da er zwei Datenbanken anzapft) mit einer Kodierung (in beiden Fällen UTF-8, da er die auf der Verarbeitungs- und Ausgabeseite braucht). Dass eine der Datenbanken von Latin1 auf UTF-8 umrechnen muss, ist korrekt. Da Latin1 Bestandteil von UTF-8 ist, sollte es hier keine Probleme geben. Ob das *immer* – also bei jeder Quellkodierung – so klappt, weiß ich nicht.
Tschö, Auge
Tach!
Nein, ich plädiere für zwei Verbindungen (die braucht Klaus eh, da er zwei Datenbanken anzapft)
Es wäre erstmal zu klären, ob zwei Datenbanken im selben Server oder zwei verschiedene Server gemeint sind. Im ersten Fall braucht es keine zwei Verbindungen - auch nicht bei zwei unterschiedlichen Kodierungen der Felder. Es ist ja sogar problemlos möglich, die Kodierungen der Felder einer Tabelle unterschiedlich einzustellen.
dedlfix.
Hello dedlfix,
Nein, ich plädiere für zwei Verbindungen (die braucht Klaus eh, da er zwei Datenbanken anzapft)
Es wäre erstmal zu klären, ob zwei Datenbanken im selben Server oder zwei verschiedene Server gemeint sind. Im ersten Fall braucht es keine zwei Verbindungen - auch nicht bei zwei unterschiedlichen Kodierungen der Felder. Es ist ja sogar problemlos möglich, die Kodierungen der Felder einer Tabelle unterschiedlich einzustellen.
Dann lass uns aber bitte nicht dumm sterben.
Wenn wir mal von zwei Datenbanken auf demselben Datenbankserver ausgehen.
Die eine ist auf latin1_general_ci und die zweite auf utf8_general_ci eingestellt.
Wie baue ich jetzt die Verbindung auf und welche Kodierung gebe ich vor?
Wie kann ich zwischen den beiden Daten austauschen, ohne etwas kaputt zu machen?
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Tach!
Dann lass uns aber bitte nicht dumm sterben.
Hab ich das nicht schon erklärt in diesem Thread? Oder zumindest im verlinkten Wiki?
Wenn wir mal von zwei Datenbanken auf demselben Datenbankserver ausgehen.
Die eine ist auf latin1_general_ci und die zweite auf utf8_general_ci eingestellt.
Dann sind das Default-Werte für neu zu erstellende Tabellen und deren Angaben sind Defaultwerte für neu zu erstellende Felder. Ansonsten hat diese Einstellung nur etwas zu sagen, welche Daten gespeichert werden können. Zwischen diesen Angaben und der Verbindungskodierung besteht kein direkter Zusammenhang (mit einer meist nicht relevanten Ausnahme - die kann man bei Interesse in der MySQL-Dokumentation nachlesen und betrifft den Unterschied zwischen SET NAMES und SET CHARACTER SET).
Wie baue ich jetzt die Verbindung auf und welche Kodierung gebe ich vor?
Du baust deine eine Verbindung auf und da verhandelst du die Kodierung an, die du sprechen möchtest. Die Kodierungen der abzufragenden Dinge sind nicht relevant.
Wie kann ich zwischen den beiden Daten austauschen, ohne etwas kaputt zu machen?
Das macht MySQL richtig, indem es gegebenenfalls zwischen der Verbindungskodierung und den Feldkodierungen umkodiert. Oder auch zwischen Feldkodierungen, wenn du Daten direkt übertragst (z.B. mit INSERT ... SELECT ...).
Und jetzt kommt noch ein Aber: Aber prinzipbedingt kann man nur dann verlustfrei umkodieren, wenn die Zielkodierung die Zeichen der Quellkodierung auch darstellen kann.
dedlfix.
Guten Morgen,
Zwischen diesen Angaben und der Verbindungskodierung besteht kein direkter Zusammenhang (mit einer meist nicht relevanten Ausnahme - die kann man bei Interesse in der MySQL-Dokumentation nachlesen und betrifft den Unterschied zwischen SET NAMES und SET CHARACTER SET).
Du baust deine eine Verbindung auf und da verhandelst du die Kodierung an, die du sprechen möchtest. Die Kodierungen der abzufragenden Dinge sind nicht relevant.
Beide DBs befinden sich auf einem Server.
Ich habe einige Seiten im Intranet, die ausschließlich auf die DB mit latin1_general_ci zugreifen, habe allerdings bisher nie beim Zugriff mit SET NAMES oder SET CHARACTER SET gearbeitet. Hier haben offenbar die Defaults für eine korrekte Darstellung gesorgt.
Nun habe ich ein kleines zugekauftes Modul eingekauft, das im Intranet eigenständig angezeigt werden soll. Diese DB ist komplett im UTF8 und alle Seiten dieses Moduls zeigen die eigenen Inhalte der eigenen Tabellen korrekt an. Soweit ich gesehen habe, wird hier auch nicht SET NAMES oder SET CHARACTER SET genutzt, also verursachen die Defaults so erstmal auch auch keine Anzeige-Probleme.
In dieser neuen DB im UTF8 habe ich eine View erstellt (damit die bereits vorhandenen Logins genutzt werden können) und nur bei der Anzeige der Daten aus dieser View, also die Daten die von DB1 kommen, werden die Umlaute nicht korrekt dargestellt.
Was muss ich denn jetzt tun, damit die Anzeige korrigiert wird?
Den Verbindungsaufbau in diesem Modul suchen und nochmal explizit das Character Set setzen?
Tach!
Beide DBs befinden sich auf einem Server.
Ich habe einige Seiten im Intranet, die ausschließlich auf die DB mit latin1_general_ci zugreifen, habe allerdings bisher nie beim Zugriff mit SET NAMES oder SET CHARACTER SET gearbeitet. Hier haben offenbar die Defaults für eine korrekte Darstellung gesorgt.
SET CHARACTER SET kannst du wieder vergessen, das macht ein paar Details anders als man sie normalerweise braucht. SET NAMES brauchst du nur, wenn du mysql(i)_set_charset() nicht zur Verfügung hast, also in ganz alten PHP-Versionen.
Nun habe ich ein kleines zugekauftes Modul eingekauft, das im Intranet eigenständig angezeigt werden soll. Diese DB ist komplett im UTF8 und alle Seiten dieses Moduls zeigen die eigenen Inhalte der eigenen Tabellen korrekt an. Soweit ich gesehen habe, wird hier auch nicht SET NAMES oder SET CHARACTER SET genutzt, also verursachen die Defaults so erstmal auch auch keine Anzeige-Probleme.
Dann wird es wohl so sein, dass das DBMS dein UTF-8 als Latin1 interpretiert. Das sieht auf den ersten Blick problemlos aus, aber der phpMyAdmin dürfte dann nicht mitspielen, weil er korrekt UTF-8 mit dem DBMS spricht, dann aber das vom DBMS angenommene Latin1 nochmal nach UTF-8 kodiert, woraufhin du doppelt-UTF-8-kodierte Zeichen hast. Oder wenn er Latin1 verwendet, geht er davon aus, solches zu bekommen und kein UTF-8, was auch zu Murks in der Anzeige führt.
In dieser neuen DB im UTF8 habe ich eine View erstellt (damit die bereits vorhandenen Logins genutzt werden können) und nur bei der Anzeige der Daten aus dieser View, also die Daten die von DB1 kommen, werden die Umlaute nicht korrekt dargestellt.
Zunächst ist CONVERT(... USING ...) gedacht um Binär-Inhalte als Text zu interpretieren. Also wenn du ein BLOB-Feld hättest und da jemand Text abgelegt hat, dann wird der als die Bytes abgelegt, die MySQL übegeben bekommt. Um ihn als Text zu verwenden, muss dessen Kodierung bekannt sein, deshalb ein USING. Wenn du allerdings Text mit bekannter Kodierung so behandelst, passiert irgendwas, was ich erst durch Versuche rausfinden müsste.
Weil du im UTF-8-Teil keine Zeichenkodierung auf der Verbindung angegeben hast und MySQL dein von Latin1 ausging, hast du nun Murks in den Feldern stehen. Diesen Murks umkodieren zu wollen macht ihn nicht besser.
Was muss ich denn jetzt tun, damit die Anzeige korrigiert wird?
Den Verbindungsaufbau in diesem Modul suchen und nochmal explizit das Character Set setzen?
Ich gehe mal davon aus, dass der alte Teil unangefasst auf Latin1 bleiben und der neue UTF-8 verwenden soll. Dann müsstest du erst einmal mit einem Programm, das korrekt mit MySQL spricht (phpMyAdmin zum Beispiel) alle Nicht-ASCII-Zeichen (Umlaute etc.) korrigieren. Dann muss der neue Teil die Verbindungskodierung UTF-8 bei jedem Verbindungsaufbau aushandeln. Der alte sollte es mit seinem Latin1 auch tun, sonst kann ein ähnliches Problem auftreten, wenn der Default-Wert mal geändert wird. Konvertierfunktionen brauchst du nicht, das kann MySQL von selbst, wenn es zu den Verbindungsangaben (oder Defaultwerten) die passend kodierten Daten bekommt.
Wenn es zu viele Daten im neuen Teil sind, dann ist händisches Korrigieren nicht praktikabel. Dann müsste es in deinem Fall gehen, einen Dump als Latin1 ausgeben zu lassen und diesen unverändert als UTF-8 zu importieren. Anschließend muss phpMyAdmin alles korrekt anzeigen. Vor solchen Versuchen bitte Kopien der Tabellen/Datenbank anlegen (mit PMAs Kopierfunktion unter "Operationen"), sonst geht vielleicht noch mehr kaputt.
dedlfix.
SET CHARACTER SET kannst du wieder vergessen, das macht ein paar Details anders als man sie normalerweise braucht. SET NAMES brauchst du nur, wenn du mysql(i)_set_charset() nicht zur Verfügung hast, also in ganz alten PHP-Versionen.
mysql_set_charset() habe ich zur Vefügung.
Dann wird es wohl so sein, dass das DBMS dein UTF-8 als Latin1 interpretiert. Das sieht auf den ersten Blick problemlos aus, aber der phpMyAdmin dürfte dann nicht mitspielen, weil er korrekt UTF-8 mit dem DBMS spricht, dann aber das vom DBMS angenommene Latin1 nochmal nach UTF-8 kodiert, woraufhin du doppelt-UTF-8-kodierte Zeichen hast. Oder wenn er Latin1 verwendet, geht er davon aus, solches zu bekommen und kein UTF-8, was auch zu Murks in der Anzeige führt.
Im PhpMyAdmin kann ich mir sowohl die Tabelle in DB1 als auch die View auf die Tabelle in DB2 mit korrekten Umlauten anzeigen lassen.
Weil du im UTF-8-Teil keine Zeichenkodierung auf der Verbindung angegeben hast und MySQL dein von Latin1 ausging, hast du nun Murks in den Feldern stehen. Diesen Murks umkodieren zu wollen macht ihn nicht besser.
Wenn PhpMyAdmin alle Umlaute in allen Tabellen korrekt anzeigt, warum sollte dann Murks in den Feldern stehen?
Was muss ich denn jetzt tun, damit die Anzeige korrigiert wird?
Den Verbindungsaufbau in diesem Modul suchen und nochmal explizit das Character Set setzen?Ich gehe mal davon aus, dass der alte Teil unangefasst auf Latin1 bleiben und der neue UTF-8 verwenden soll.
Das ist richtig, zumindest vorerst. Mittelfristig werde ich schauen, wie die Tabellen nach einer Sicherheitskopie auf UTF8 umgesetzt aussehen, bzw. der Inhalt
Dann müsstest du erst einmal mit einem Programm, das korrekt mit MySQL spricht (phpMyAdmin zum Beispiel) alle Nicht-ASCII-Zeichen (Umlaute etc.) korrigieren. Dann muss der neue Teil die Verbindungskodierung UTF-8 bei jedem Verbindungsaufbau aushandeln.
Ich verstehe leider nicht, inwiefern ich wo etwas inhaltlich korrigieren kann, da der Inhalt der Tabelle aus DB1 unangetastet bleiben muss und die View ja selbst keine Daten enthält.
Aber ich werde versuchen, im neuen Modul die Verbindungskodierung immer mitzugeben.
Im alten Teil ist das leider sehr sehr umfangreich, da der Verbindungsaufbau an sehr vielen Stellen durchgeführt wird. (Ist leider so gewachsen und kaum noch korrigierbar)
Tach!
Im PhpMyAdmin kann ich mir sowohl die Tabelle in DB1 als auch die View auf die Tabelle in DB2 mit korrekten Umlauten anzeigen lassen.
Wenn PhpMyAdmin alle Umlaute in allen Tabellen korrekt anzeigt, warum sollte dann Murks in den Feldern stehen?
Meine Schlussfolgerungen werden falsch, wenn die Gegebenheiten doch andere sind, als ich bisher kannte. Wenn der phpMyAdmin in beiden Fällen richtige Umlaute anzeigen kann, sind die Daten deines neuen Moduls wohl doch richtig kodiert im System gelandet. Das würde bedeuten, dass dieses die Verbindungskodierung richtig setzt. Oder eher unwahrscheinlich (weil unsinnig, wenn man mit UTF-8 im Frontend arbeitet), alles nach Latin1 umkodiert.
Dann müsstest du erst einmal mit einem Programm, das korrekt mit MySQL spricht (phpMyAdmin zum Beispiel) alle Nicht-ASCII-Zeichen (Umlaute etc.) korrigieren. Dann muss der neue Teil die Verbindungskodierung UTF-8 bei jedem Verbindungsaufbau aushandeln.
Ich verstehe leider nicht, inwiefern ich wo etwas inhaltlich korrigieren kann, da der Inhalt der Tabelle aus DB1 unangetastet bleiben muss und die View ja selbst keine Daten enthält.
Wenn alles gut vom PMA angezeigt wird, ist keine Korrektur notwendig. Dann sollte aber auch ohne irgendwelche händischen Umkodierungen alles korrekt ablaufen.
Aber ich werde versuchen, im neuen Modul die Verbindungskodierung immer mitzugeben.
Schau mal, ob es da wirklich fehlt.
Im alten Teil ist das leider sehr sehr umfangreich, da der Verbindungsaufbau an sehr vielen Stellen durchgeführt wird. (Ist leider so gewachsen und kaum noch korrigierbar)
Es gibt Editoren, die können in einem Verzeichnis nach Vorkommen von mysql_connect() suchen. Da ein mysql_set_charset(...) hinzuzufügen, ist so aufwendig nun auch wieder nicht.
dedlfix.
Aber ich werde versuchen, im neuen Modul die Verbindungskodierung immer mitzugeben.
Schau mal, ob es da wirklich fehlt.
Da war nichts explizit gesetzt worden.
Es wird mit einer Klasse gearbeitet, daher bin ich mir ziemlich sicher, dass ich nicht nach allen Vorkommen von mysqli_connect suchen muss.
class db
{
var $link;
public function connect()
{
$this->link=mysqli_connect(SQL_IP,SQL_USER,SQL_PWD,SQL_DATABASE) or die(db::error($this->link));
mysqli_query($this->link,"SET @@SESSION.sql_mode = ''") or die(db::error($this->link));
}
Ich habe die folgenden 2 Zeilen hinzugefügt, aber es hatte keinerlei Auswirkungen auf die Anzeige der Umlaute.
mysqli_query($this->link,"SET character_set_results = 'utf8', character_set_client = 'utf8', character_set_connection = 'utf8', character_set_database = 'utf8', character_set_server = 'utf8'") or die(db::error($this->link));
mysqli_set_charset($this->link,"utf8") or die(db::error($this->link));
Hello,
Ich habe die folgenden 2 Zeilen hinzugefügt, aber es hatte keinerlei Auswirkungen auf die Anzeige der Umlaute.
Mit welchem Character-Set arbeitet denn Deine Anzeige? Die kann ja nur eine zur selben Zeit.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Ich habe die folgenden 2 Zeilen hinzugefügt, aber es hatte keinerlei Auswirkungen auf die Anzeige der Umlaute.
Mit welchem Character-Set arbeitet denn Deine Anzeige? Die kann ja nur eine zur selben Zeit.
Laut Seiteninformationen ist das verwendete Charset des neuen Moduls UTF8.
Die "alten" Seiten sind ISO-8859.
Hello,
Mit welchem Character-Set arbeitet denn Deine Anzeige? Die kann ja nur eine zur selben Zeit.
Laut Seiteninformationen ist das verwendete Charset des neuen Moduls UTF8.
Die "alten" Seiten sind ISO-8859.
Naja, du musst doch sehen können, welche Kodierung der Browser vorgeschlagen bekommt, entweder im HTTP-Header oder als Meta-Tag oder beides (und dann hoffentlich gleichlautend).
Und deine generelle-Webserver-Einstellung fürs Character-Set spielt da ggf. auch noch mit.
Und wenn Du dann is Modul reinschaust und lauter mb_*-Funktionen findest, wird es wohl auf Multibyte ausgelegt sein. Kannst Du denn irgendwo eine Angabe
header('Content-Type: text/html; Charset=utf8')
oder ähnlich (xhtml) finden?
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Tach!
Naja, du musst doch sehen können, welche Kodierung der Browser vorgeschlagen bekommt, entweder im HTTP-Header oder als Meta-Tag oder beides (und dann hoffentlich gleichlautend).
Bitte nicht auch noch diese Baustelle hinzufügen. urlencode() sollte Klarheit bezüglich des Datenbankproblems bringen. Es kann natürlich auch (noch) sein, dass das Problem zwischen PHP und dem Browser liegt. Aber das würde ich erst dann angehen, wenn das DBMS-Problem zweifelsfrei geklärt ist.
dedlfix.
Hello,
Naja, du musst doch sehen können, welche Kodierung der Browser vorgeschlagen bekommt, entweder im HTTP-Header oder als Meta-Tag oder beides (und dann hoffentlich gleichlautend).
Bitte nicht auch noch diese Baustelle hinzufügen. urlencode() sollte Klarheit bezüglich des Datenbankproblems bringen. Es kann natürlich auch (noch) sein, dass das Problem zwischen PHP und dem Browser liegt. Aber das würde ich erst dann angehen, wenn das DBMS-Problem zweifelsfrei geklärt ist.
Ja genau. Ich will die Baustelle ausschließen, indem ich mir Gewissheit darüber verschaffe, was der Browser bekommt und tut.
Es nützt doch nichts, den blauen Himmel immer durch ein Graufilter anzuschauen und dann zu mutmaßen, das Wetter könnte schlecht sein ;-P.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Naja, du musst doch sehen können, welche Kodierung der Browser vorgeschlagen bekommt, entweder im HTTP-Header oder als Meta-Tag oder beides (und dann hoffentlich gleichlautend).
bei meinen alten Seiten weiß ich, dass ich über den Meta-Tag den content-type auf ISO-8859-1 setze. (<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">)
Beim neuen Modul wird über ein Meta-Tag der Charset auf UTF8 gesetzt. (<meta charset="utf-8">)
Was die Seite dann letztlich anzeigt, kann aber doch auch jederzeit über die Seiteninformationen unter Kodierung angeschaut werden.
Hello,
Naja, du musst doch sehen können, welche Kodierung der Browser vorgeschlagen bekommt, entweder im HTTP-Header oder als Meta-Tag oder beides (und dann hoffentlich gleichlautend).
bei meinen alten Seiten weiß ich, dass ich über den Meta-Tag den content-type auf ISO-8859-1 setze. (<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">)
Beim neuen Modul wird über ein Meta-Tag der Charset auf UTF8 gesetzt. (<meta charset="utf-8">)
HTTP-Header-Informationen haben üblicherweise Vorrang.
Meta und Header können nur noch vom Bentuzer selber über die erzwungene Codierungsangabe direkt im Browsermenu geändert werden. Das lassen wir hier jetzt aber mal außen vor.
Was die Seite dann letztlich anzeigt, kann aber doch auch jederzeit über die Seiteninformationen unter Kodierung angeschaut werden.
Vermutlich wird Dein Server mit seiner generellen Angabe im Header die Meta-Angaben überbieten?
Hast Du schon mal die Header angeschaut?
Wenn die Anzeige-Codierung feststeht Ende der Kette), können wir Schritt für Schritt rückwärts suchen, wo in der Kette etwas umgebogen wird.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Vermutlich wird Dein Server mit seiner generellen Angabe im Header die Meta-Angaben überbieten?
Hast Du schon mal die Header angeschaut?
ich wüsste jetzt gar nicht wo ich da nachschauen könnte, ob der Server überhaupt irgednwelche Meta-Angaben überbietet oder nicht.
Wenn die Anzeige-Codierung feststeht Ende der Kette), können wir Schritt für Schritt rückwärts suchen, wo in der Kette etwas umgebogen wird.
Wenn mit rechts-Klick auf die fertig geladene Seite "Seiteninformationen anzeigen" auswähle und mir hier als Kodierung UTF8 und als content-type utf8 angezeigt wird, dann kann ich das doch als "Ende der Kette" annehmen oder nicht?
Hello,
Wenn mit rechts-Klick auf die fertig geladene Seite "Seiteninformationen anzeigen" auswähle und mir hier als Kodierung UTF8 und als content-type utf8 angezeigt wird, dann kann ich das doch als "Ende der Kette" annehmen oder nicht?
Scheint so zu sein.
Ist das jetzt bei allen Seiten der Fall, auch bei den alten?
Nur aus Interesse: Du benutzt einen Firefox? Welche Version?
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Wenn mit rechts-Klick auf die fertig geladene Seite "Seiteninformationen anzeigen" auswähle und mir hier als Kodierung UTF8 und als content-type utf8 angezeigt wird, dann kann ich das doch als "Ende der Kette" annehmen oder nicht?
Scheint so zu sein.
Ist das jetzt bei allen Seiten der Fall, auch bei den alten?
Nein, UTF8 wird nur bei den neuen Seiten angezeigt. Bei den alten wird ISO-8859-1 angezeigt.
Nur aus Interesse: Du benutzt einen Firefox? Welche Version?
Firefox 28.0, sollte die aktuellste sein, oder?
Hello,
Wenn mit rechts-Klick auf die fertig geladene Seite "Seiteninformationen anzeigen" auswähle und mir hier als Kodierung UTF8 und als content-type utf8 angezeigt wird, dann kann ich das doch als "Ende der Kette" annehmen oder nicht?
Scheint so zu sein.
Ist das jetzt bei allen Seiten der Fall, auch bei den alten?Nein, UTF8 wird nur bei den neuen Seiten angezeigt. Bei den alten wird ISO-8859-1 angezeigt.
Ok, dann sollte das doch nun klappen. Zwei Verbindungen aufbauen, zwei Codierungen aushandeln und dann bei den Ausgabestrom der Seiten, die ISO machen in UTF-8 umwandeln.
Das könnte mit auto_prepend_file und ob_start(), sowie auto_append_file, mb_check_encoding() und mb_convert_encoding() funktionieren. Das ist dann die Hammer-Methode.
Alternativ musst Du alle alten Scripte harmonisieren.
Nur aus Interesse: Du benutzt einen Firefox? Welche Version?
Firefox 28.0, sollte die aktuellste sein, oder?
Ich habe nur gefragt, weil ich abschätzen wollte, ob ich dann so ungefähr das Gleiche sehe, wie Du :-)
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Ok, dann sollte das doch nun klappen. Zwei Verbindungen aufbauen, zwei Codierungen aushandeln und dann bei den Ausgabestrom der Seiten, die ISO machen in UTF-8 umwandeln.
Das könnte mit auto_prepend_file und ob_start(), sowie auto_append_file, mb_check_encoding() und mb_convert_encoding() funktionieren. Das ist dann die Hammer-Methode.
Alternativ musst Du alle alten Scripte harmonisieren.
ich baue ja derzeit schon 2 Verbindungen auf. Eine Verbindung für die alten Seiten und eine Verbindung für die neuen Seiten.
Und bei den alten Seiten (die noch ISO machen) gibt es ja keine Ausgabeprobleme, nur bei den neuen Seiten und da auch einzig nur da, wo die View angezeigt werden soll, die Inhalte aus der alten DB heranzieht.
Und wo ich die Kodierung bei den neuen Seiten ausgehandelt hatte, hatte das keine Auswirkung auf die fehlerhafte Anzeige der Umlaute in der View.
Ich verstehe nicht, warum der Phpmyadmin da keine Probleme bei der Anzeige der Inhalte beider DBs hat.
Vermutlich ist es am sinnvollsten, wenn ich die gesamte Latin1-DB mit allen Tabellen und allen Felder in UTF8 ändere und alle Seiten nach den META-Angaben durchsuche, um dort anstelle von ISO UTF8 zu setzen.
Ich dachte, man könnte einfach die View insoweit abändern, dass eine UTF8-kodierte Seite die Inhalte korrekt darstellt.
Hallo
ich baue ja derzeit schon 2 Verbindungen auf. Eine Verbindung für die alten Seiten und eine Verbindung für die neuen Seiten.
Und bei den alten Seiten (die noch ISO machen) gibt es ja keine Ausgabeprobleme, nur bei den neuen Seiten und da auch einzig nur da, wo die View angezeigt werden soll, die Inhalte aus der alten DB heranzieht.
Ziehen wir es mal glatt. Du hast einen View mit Inhalten aus der Datenbank 1 (DB1), deren Inhalte in ISO-8859-1 kodiert sind und weiteren Inhalten aus der Datenbank 2 (DB2), deren Inhalte im Gegensatz zu DB1 mit UTF-8 kodiert sind. Der Fehler tritt ausschließlich auf, wenn der fragliche View angezeigt werden soll.
Ist der View in DB1 oder in DB2? Mit welcher Kodierung erfolgt der Abruf der Daten des Views?
Ich vermute, dass der Fehler schon im View steckt, sprich, dass dort einerseits ISO-8859-kodierte aber auch UTF-8-kodierte Inhalte drin sind. Beim Abruf der Daten wird natürlich nur eine der beiden Kodierungen benutzt. Falls MySQL anders als angenommen, hier nicht automatisch (unterschiedlich) umkodiert, muss der Inhalt aus einer der beiden Quellen falsch kodiert sein.
Tschö, Auge
Tach!
Ziehen wir es mal glatt. Du hast einen View mit Inhalten aus der Datenbank 1 (DB1), deren Inhalte in ISO-8859-1 kodiert sind und weiteren Inhalten aus der Datenbank 2 (DB2), deren Inhalte im Gegensatz zu DB1 mit UTF-8 kodiert sind.
Das Statement im Ausgangsposting fragt nur Daten aus DB2 ab. Da ist kein Join, der Tabellen aus beiden Datenbanken anspricht.
Ich vermute, dass der Fehler schon im View steckt, sprich, dass dort einerseits ISO-8859-kodierte aber auch UTF-8-kodierte Inhalte drin sind.
Das darf ebensowenig ein Problem sein, wie es zwei unterschiedlich kodierte Felder in ein und derselben Tabelle sind. Beim Abfragen wird das eine Feld und das andere nicht oder umgekehrt oder alle beide in die Verbindungskodierung umkodiert, je nachdem wie unterschiedlich die drei Kodierungen sind. Und weder bei der View noch bei der Tabelle muss man händisch irgendwas durch CONVERT() schicken (denn das ist ja auch gar nicht für Text-Felder da).
Beim Abruf der Daten wird natürlich nur eine der beiden Kodierungen benutzt.
Oder auch eine ganz andere - theoretisch jedenfalls. Hier ist es eine von beiden. Das ändert an der Arbeitsweise MySQLs prinzipiell nichts.
Falls MySQL anders als angenommen, hier nicht automatisch (unterschiedlich) umkodiert, muss der Inhalt aus einer der beiden Quellen falsch kodiert sein.
Angeblich ja nicht, laut phpMyAdmin-Beobachtung.
dedlfix.
Tach!
'n Abend
Ziehen wir es mal glatt. Du hast einen View mit Inhalten aus der Datenbank 1 (DB1), deren Inhalte in ISO-8859-1 kodiert sind und weiteren Inhalten aus der Datenbank 2 (DB2), deren Inhalte im Gegensatz zu DB1 mit UTF-8 kodiert sind.
Das Statement im Ausgangsposting fragt nur Daten aus DB2 ab. Da ist kein Join, der Tabellen aus beiden Datenbanken anspricht.
Wenn ich mich nicht auf das irgendwann gelesene verlassen hätte, märe mir das auch aufgefallen.
Beim Abruf der Daten wird natürlich nur eine der beiden Kodierungen benutzt.
Oder auch eine ganz andere - theoretisch jedenfalls. Hier ist es eine von beiden. Das ändert an der Arbeitsweise MySQLs prinzipiell nichts.
Ok, nächster Versuch.
In DB1 (ISO-8859-1) wird ein View ausschließlich mit Daten aus DB2 (UTF-8) erstellt. Welche der beiden Kodierungen wird dabei verwendet? Werden die UTF-8-kodierten Daten nach ISO-8859-1 umgerechnet, da die DB1 genau so kodiert ist? Warum brauche ich in DB1 einen View, der ausschließlich aus Daten der DB2 besteht? Warum habe ich diesen View nicht in DB2, wo er, wenn er, wie es scheint, nur der Ausgabe und nicht der Weiterverarbeitung in DB1 dient, richtig aufgehoben wäre?
Tschö, Auge
Tach!
In DB1 (ISO-8859-1) wird ein View ausschließlich mit Daten aus DB2 (UTF-8) erstellt. Welche der beiden Kodierungen wird dabei verwendet? Werden die UTF-8-kodierten Daten nach ISO-8859-1 umgerechnet, da die DB1 genau so kodiert ist?
Die Datenbank-Kodierungen spielen keine Rolle, solange nicht irgendwelche String-Vergleiche mit Feldern unterschiedlicher Kodierungen in der View drin sind. Wie die allerdings gehandhabt werden, entzieht sich grad meiner Kenntnis. Das passiert aber alles intern.
Warum brauche ich in DB1 einen View, der ausschließlich aus Daten der DB2 besteht? Warum habe ich diesen View nicht in DB2, wo er, wenn er, wie es scheint, nur der Ausgabe und nicht der Weiterverarbeitung in DB1 dient, richtig aufgehoben wäre?
Die erste Frage kommt auf die Aufgabenstellung an. Bei der zweiten spielt es in Bezug auf Zeichenkodierungen keine Rolle, wo sich die View befindet. Das Problem tritt auch mit unterschiedlichen Feldkodierungen in nur einer einzigen Tabelle auf. Und solange die Daten zur Kodierung passend in das DBMS gelangt sind, spielt das alles für das Übertragen zum abfragenden Client ebenfalls keine Rolle, denn auf der Verbindung wird die dort ausgehandelte Kodierung gesprochen, und dazu kodiert MySQL entsprechend um.
dedlfix.
Guten Morgen,
Ist der View in DB1 oder in DB2? Mit welcher Kodierung erfolgt der Abruf der Daten des Views?
Die View ist in der DB, die komplett UTF8-kodiert ist und zieht ausschließlich Daten aus der DB die Latin1-kodiert ist.
Hintergrund ist der, dass für die neuen Seiten auch Logins verwendet werden. Damit die Mitarbeiter sich nicht neue Logins erstellen und merken müssen, sorgt die View dafür, dass auch wenn in DB1 Mitarbeiter (mit deren Logins) geändert, gelöscht oder hinzugefügt werden, dass die neuen Seiten das auch sofort mitbekommen.
create or replace view v_imported_users as
SELECT a.idnr as UserID,
a.loginname as UserName,
a.passwort as Password,
convert(b.name using utf8) collate utf8_general_ci as Name,
convert(b.vorname using utf8) collate utf8_general_ci as Surname,
b.email as email,
1 AS group_id, 'nophoto.jpg' as user_photo
FROM DB2.logins as a left join DB2.employees as b on a.loginname = b.pnr
where b.sichtbar <> 'N' AND b.kst <> ''
Ich glaube nicht, dass unterschiedliche Kodierungen auf Feldebene in der View Probleme machen, da es sonst keinen Sinn macht, unterschiedliche Kodierungen auf Feldebene überhaupt zu unterstützen.
Klaus
Hello,
Ich glaube nicht, dass unterschiedliche Kodierungen auf Feldebene in der View Probleme machen, da es sonst keinen Sinn macht, unterschiedliche Kodierungen auf Feldebene überhaupt zu unterstützen.
Das was drauf steht, sollte auch drin sein. Die Datenbank denkt schließlich nicht, sie führt nur starre Regeln aus.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hello,
ich baue ja derzeit schon 2 Verbindungen auf. Eine Verbindung für die alten Seiten und eine Verbindung für die neuen Seiten.
Und bei den alten Seiten (die noch ISO machen) gibt es ja keine Ausgabeprobleme, nur bei den neuen Seiten und da auch einzig nur da, wo die View angezeigt werden soll, die Inhalte aus der alten DB heranzieht.
Ich habe das bisher stillschweigend vorausgesetzt. Benutzt Du überhaupt PHP für die Scripte?
Werden die Views mittels API (PHP) aufgebaut oder durch die DB?
https://dev.mysql.com/doc/refman/5.1/de/create-view.html
Wird die Codierung mittles Header() dort wieder umgeschaltet auf ISO-8859-1?
Wenn Du multibyte-codierte Daten durch Scripte jagst, die nur für singlebyte-codierte gebaut sind, kann es schon Probleme geben bei der Zeichenzählung, Funktionen, wie strtolower, strtoupper, substr, usw.
Und wo ich die Kodierung bei den neuen Seiten ausgehandelt hatte, hatte das keine Auswirkung auf die fehlerhafte Anzeige der Umlaute in der View.
Wahrscheinlich hast Du noch nicht genau genug geschildert, was in welcher Reihenfolge geschieht. Sonst müsste man den Fehler doch einkreisen können :-O
Ich verstehe nicht, warum der Phpmyadmin da keine Probleme bei der Anzeige der Inhalte beider DBs hat.
Weil der mWn immer nur eine Verbindung gleichzeitig bearbeitet/anzeigt?
Vermutlich ist es am sinnvollsten, wenn ich die gesamte Latin1-DB mit allen Tabellen und allen Felder in UTF8 ändere und alle Seiten nach den META-Angaben durchsuche, um dort anstelle von ISO UTF8 zu setzen.
Das hat ja nur sinn, wenn auch alle Scripte dazu geändert werden.
Ich dachte, man könnte einfach die View insoweit abändern, dass eine UTF8-kodierte Seite die Inhalte korrekt darstellt.
Siehe Frage oben. View per DB oder per Script?
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Guten Morgen,
Ich habe das bisher stillschweigend vorausgesetzt. Benutzt Du überhaupt PHP für die Scripte?
Werden die Views mittels API (PHP) aufgebaut oder durch die DB?
Ja, ich verwende PHP für die Scripte und die View ist in der DB gebaut und nicht über die PHP-API.
Klaus
Hello,
Guten Morgen,
Ich habe das bisher stillschweigend vorausgesetzt. Benutzt Du überhaupt PHP für die Scripte?
Werden die Views mittels API (PHP) aufgebaut oder durch die DB?Ja, ich verwende PHP für die Scripte und die View ist in der DB gebaut und nicht über die PHP-API.
Dann kommen in der API also tatsächlich zweierlei Codierungen an.
Dann würde ich jetzt zuerst mal Auges Hinweis verfolgen:
https://forum.selfhtml.org/?t=217248&m=1491992
Damit müsste es möglich sein, beide Views mit derselben Codierung erstellen zu lassen. Ich denek aber, dass MySQL "Set Names" nicht mehr gerne sieht. Kommt allerdings darauf an... Wenn Du Encoding und Collation gleichzeitig umschalten willst, was mMn ja sinnvoll ist, tut es ja seine Aufgabe. Ich habe die Doku und Dedlfix Erläuterungen zu diesem Punkt noch nicht ganz durchschaut.
Wenn der Inhalt erstmal stimmt, kommt es nur noch auf das "Transfer-Encoding", die passende Verarbeitung (mb_*-Funktionen in der API) und die passende Darstellung am Front-End an. Da finden ja auch noch ein Transfer und eine Interpretation statt.
Ein Punkt ist vielleicht noch kritisch (?)
Wenn die View statische Referenzen enthält, wird es wahrscheinlich relevant sein, mit welcher Codierung die nun wieder erfasst worden sind.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Tach!
Damit müsste es möglich sein, beide Views mit derselben Codierung erstellen zu lassen.
Views haben keine Kodierungsangabe. Erst zur Laufzeit wird diese interessant, aber ob View oder direktes Statement, ist belanglos.
Ich denek aber, dass MySQL "Set Names" nicht mehr gerne sieht.
SET NAMES ist eine Erleichterung, um drei Konfigurationswerte gleichzeitig zu setzen. Dasselbe macht die MySQL-API-Funktion mysql_set_character_set() auch, nur dass sie zusätzlich im Client noch die verwendete Kodierung vermerkt, so dass mysql_real_escape_string() richtig arbeiten kann. Das ist aber für ASCII-basierende Kodierungen unerheblich, weil alle zu behandelnden Zeichen im ASCII-Teil liegen und es somit egal ist, weil das Ergebnis stets dasselbe ist und der Rest nicht beeinflusst wird.
Wenn die Client-API die Kodierung nicht kennt, ist das auch kein Beinbruch für die Daten, denn diese werden von ihr nicht verändert oder interpretiert, sondern nur durchgereicht. SET NAMES oder mysql_set_character_set() zu verwenden, nimmt sich praktisch also gar nichts. Demzufolge ist ein "nicht gerhe sehen" ohne Grundlage.
Kommt allerdings darauf an... Wenn Du Encoding und Collation gleichzeitig umschalten willst, was mMn ja sinnvoll ist, tut es ja seine Aufgabe.
Eine Kollationsangabe hängt immer hinter einer Kodierung. Die gibt es nicht einzeln. Man kann die Kodierung ohne Kollationsberücksichtigung umschalten, wenn man keine Stringvergleiche hat. Man kann aber nicht die Kollation nachträglich wechseln, das geht nur in Einheit mit der Kodierung.
Eine Kollationsangabe auf einer Verbindung ist nur dann interessant, wenn in den Statements Stringvergleiche vorkommen. Wenn Feldinhalte verglichen werden, mit literalen Strings im Staement oder mit anderen Feldern, dann ist die Feld-Kollationsangabe entscheidend und die Kollation der Verbindung bedeutungslos. Das heißt, dass man die Verbindungskollation üblicherweise unbeachtet lassen kann, denn Vergleiche zwischen literalen Strings im Statement sind eigentlich sinnlos und könnten gleich durch ihr Ergebnis ersetzt werden.
Ein Punkt ist vielleicht noch kritisch (?)
Wenn die View statische Referenzen enthält, wird es wahrscheinlich relevant sein, mit welcher Codierung die nun wieder erfasst worden sind.
Nö, du hast ja eine Kodierung auf der Verbindung ausgehandelt. Gemäß dieser werden die Statements interpretiert. Der Rest ist dann MySQLs Sache.
dedlfix.
Hallo
Hast Du schon mal die Header angeschaut?
ich wüsste jetzt gar nicht wo ich da nachschauen könnte, ob der Server überhaupt irgednwelche Meta-Angaben überbietet oder nicht.
Das tut er. Ein Tip, da du Firefox nutzt. Der Browser hat, wie die anderen auch, Werkzeuge für die Webentwicklung dabei. Über Extras→Web-Entwickler kannst du sie starten. In der Web-Konsole werden alle nach einem Request geladenen Ressourcen aufgelistet (die Seite, CSS- und JavaScript-Dateien, Bilder, etc.). Mit einem Klick auf ein Element der Auflistung wird dir der Request, seine Header und die Header der Antwort gelistet. Dort kannst du u.A. sehen, mit welcher Kodierung eine Seite/Text-Ressource ausgeliefert wurde.
Andere Browser können das, wie gesagt, auch. Da kenne ich aber nicht den Weg durch die Menüs.
Tschö, Auge
Tach!
Mit einem Klick auf ein Element der Auflistung wird dir der Request, seine Header und die Header der Antwort gelistet. Dort kannst du u.A. sehen, mit welcher Kodierung eine Seite/Text-Ressource ausgeliefert wurde.
Darf ich das etwas genauer formulieren? Die charset-Angabe im HTTP-Header zeigt nur an, wie die Ausgabe deklariert ist, nicht in welcher Kodierung sie tatsächlich ausgeliefert wird. Also, das ist nur das was in den Zollpapieren steht, nicht das was im Paket ist.
dedlfix.
Hallo
Mit einem Klick auf ein Element der Auflistung wird dir der Request, seine Header und die Header der Antwort gelistet. Dort kannst du u.A. sehen, mit welcher Kodierung eine Seite/Text-Ressource ausgeliefert wurde.
Darf ich das etwas genauer formulieren? Die charset-Angabe im HTTP-Header zeigt nur an, wie die Ausgabe deklariert ist, nicht in welcher Kodierung sie tatsächlich ausgeliefert wird. Also, das ist nur das was in den Zollpapieren steht, nicht das was im Paket ist.
Noch genauer: Es ist die Kodierung, von der der Server behauptet, dass es die zutreffende ist.
Noch was? :-)
Tschö, Auge
Tach!
Ich habe die folgenden 2 Zeilen hinzugefügt, aber es hatte keinerlei Auswirkungen auf die Anzeige der Umlaute.
Mit welchem Character-Set arbeitet denn Deine Anzeige? Die kann ja nur eine zur selben Zeit.
Es ist ratsam, nicht auch noch die Interpretationsmöglichkeiten des Browsers zum eigentlichen Problem hinzuzufügen. Gleich nach dem Fetchen die Daten durch ein urlencode() zu schicken und das Ergebnis anzuzeigen, zeigt ausreichend exakt an, welche Bytes für die Nicht-ASCII-Zeichen in der Zeichenkette enthalten sind. (bin2hex() tuts auch, ist aber unübersichtlicher.) urlencode() liefert nur ASCII-Zeichen zurück, die üblicherweise nicht auch noch vom Browser (fehl)interpretiert werden.
dedlfix.
Hello,
class db
{
var $link;public function connect()
{
$this->link=mysqli_connect(SQL_IP,SQL_USER,SQL_PWD,SQL_DATABASE) or die(db::error($this->link));
mysqli::set_charset ( 'utf8' ) or die db::error($this->link);
mysqli_query($this->link,"SET @@SESSION.sql_mode = ''") or die(db::error($this->link));
}
>
> Ich habe die folgenden 2 Zeilen hinzugefügt, aber es hatte keinerlei Auswirkungen auf die Anzeige der Umlaute.
>
> ~~~php
> mysqli_query($this->link,"SET character_set_results = 'utf8', character_set_client = 'utf8', character_set_connection = 'utf8', character_set_database = 'utf8', character_set_server = 'utf8'") or die(db::error($this->link));
> mysqli_set_charset($this->link,"utf8") or die(db::error($this->link));
>
Im Object reicht
mysqli::set_charset ( 'utf8' ) or die db::error($this->link);
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Tach!
Aber ich werde versuchen, im neuen Modul die Verbindungskodierung immer mitzugeben.
Schau mal, ob es da wirklich fehlt.
Da war nichts explizit gesetzt worden.
Es wird mit einer Klasse gearbeitet, daher bin ich mir ziemlich sicher, dass ich nicht nach allen Vorkommen von mysqli_connect suchen muss.
Dann bin ich mit meinem Latein am Ende. Da ist irgendwas, was mir grad nicht einfällt, was es sein könnte. Denn es passt nicht zusammen, wenn der Client UTF-8 sendet, MySQL aber Latin1 annimmt und der phpMyAdmin trotzdem die Umlaute richtig anzeigen kann.
$this->link=mysqli_connect(SQL_IP,SQL_USER,SQL_PWD,SQL_DATABASE) or die(db::error($this->link));
mysqli_query($this->link,"SET @@SESSION.sql_mode = ''") or die(db::error($this->link));
Jemanden sterben zu lassen, nur weil er mal einen Husten hat und den Besuchern einen ausführlichen Autopsiebericht zukommen zu lassen, der für sie gar nicht interessant ist, ist nicht gerde State-of-the-Art-Programmierung. Aber das nur nebenbei.
Ich habe die folgenden 2 Zeilen hinzugefügt, aber es hatte keinerlei Auswirkungen auf die Anzeige der Umlaute.
mysqli_query($this->link,"SET character_set_results = 'utf8', character_set_client = 'utf8', character_set_connection = 'utf8', character_set_database = 'utf8', character_set_server = 'utf8'") or die(db::error($this->link));
mysqli_set_charset($this->link,"utf8") or die(db::error($this->link));
Die erste Zeile ist nutzlos, weil alle Werte von der zweiten Zeile wieder überschrieben werden.
Und wenn es keine Auswirkungen hat, müsste eigentlich die Default-Kodierung bereits UTF-8 sein. Das passt dann aber nicht zu deinen alten Programmteilen.
Du kannst mal, ohne die Kodierung selbst zu setzen, SHOW VARIABLES LIKE 'char%' als Abfrage starten und dann das Ergebnis ganz normal fetchen und ausgeben:
~~~php
// ggf. $this->link anpassen und für $result und $row andere Namen nehmen, wenn sie mit vorhandenen kollidieren
$result = mysqli_query($this->link, "SHOW VARIABLES LIKE 'char%'");
while ($row = mysqli_fetch_assoc($result))
print_r($row);
Das mal direkt nach dem Verbindungsaufbau und einmal kurz vor (oder nach) der/einer Abfrage, die korrekte Daten anzeigt.
dedlfix.
Dann bin ich mit meinem Latein am Ende. Da ist irgendwas, was mir grad nicht einfällt, was es sein könnte. Denn es passt nicht zusammen, wenn der Client UTF-8 sendet, MySQL aber Latin1 annimmt und der phpMyAdmin trotzdem die Umlaute richtig anzeigen kann.
Ich habe mir die Seiteninformationen vom phpmyadmin, den "alten" Seiten und des neuen Moduls anzeigen lassen:
PhpMyAdmin und das neue Modul verwenden als Charset UTF8, meine alten Seiten ISO-8859-1.
mysqli_query($this->link,"SET character_set_results = 'utf8', character_set_client = 'utf8', character_set_connection = 'utf8', character_set_database = 'utf8', character_set_server = 'utf8'") or die(db::error($this->link)); mysqli_set_charset($this->link,"utf8") or die(db::error($this->link));
>
> Die erste Zeile ist nutzlos, weil alle Werte von der zweiten Zeile wieder überschrieben werden.
>
Ich hatte auch erst nur die erste Zeile und anschließend die 2. Zeile hinzugenommen.
> Und wenn es keine Auswirkungen hat, müsste eigentlich die Default-Kodierung bereits UTF-8 sein. Das passt dann aber nicht zu deinen alten Programmteilen.
Die alten Programmteile nehmen auch keinen Zugriff auf die neue DB, daher hat es wohl keine Auswirkung. In den alten Programmteilen wird auf jeder Seite explizit das Charset ISO-8859-1 gesetzt.
>
> Du kannst mal, ohne die Kodierung selbst zu setzen, SHOW VARIABLES LIKE 'char%' als Abfrage starten und dann das Ergebnis ganz normal fetchen und ausgeben:
>
> ~~~php
// ggf. $this->link anpassen und für $result und $row andere Namen nehmen, wenn sie mit vorhandenen kollidieren
> $result = mysqli_query($this->link, "SHOW VARIABLES LIKE 'char%'");
> while ($row = mysqli_fetch_assoc($result))
> print_r($row);
Das mal direkt nach dem Verbindungsaufbau und einmal kurz vor (oder nach) der/einer Abfrage, die korrekte Daten anzeigt.
Das funktioniert leider nicht so richtig, da die Anzeige direkt beim Verbindungsaufbau direkt wieder überschrieben wird. Zu schnell, um mittels Screenshot zu reagieren oder etwas zu lesen.
Beim Einfügen der Zeilen unmittelbar vor oder nach der Abfrage wird gar nichts ausgegeben (oder direkt wieder überschrieben). Oder ich habe nicht die richtigen Stellen gefunden.
Tach!
Das mal direkt nach dem Verbindungsaufbau und einmal kurz vor (oder nach) der/einer Abfrage, die korrekte Daten anzeigt.
Das funktioniert leider nicht so richtig, da die Anzeige direkt beim Verbindungsaufbau direkt wieder überschrieben wird. Zu schnell, um mittels Screenshot zu reagieren oder etwas zu lesen.
Dann füg ein die(); hinten an, dann kann Nachfolgendes nicht mehr reinpfuschen. Es sei denn, vorher war bereits ein Location-Header ober ähnliches gesendet worden. Eine Alternative wäre die Ausgabe in eine Datei.
dedlfix.
Dann füg ein die(); hinten an, dann kann Nachfolgendes nicht mehr reinpfuschen. Es sei denn, vorher war bereits ein Location-Header ober ähnliches gesendet worden. Eine Alternative wäre die Ausgabe in eine Datei.
Gute Idee... hier schonmal die Zeilen von der Ausgabe direkt hinter dem Connect:
Zuerst ohne mysqli_set_charset utf8:
Array ( [Variable_name] => character_set_client [Value] => latin1 ) Array ( [Variable_name] => character_set_connection [Value] => latin1 ) Array ( [Variable_name] => character_set_database [Value] => utf8 ) Array ( [Variable_name] => character_set_filesystem [Value] => binary ) Array ( [Variable_name] => character_set_results [Value] => latin1 ) Array ( [Variable_name] => character_set_server [Value] => latin1 ) Array ( [Variable_name] => character_set_system [Value] => utf8 ) Array ( [Variable_name] => character_sets_dir [Value] => c:\xampp\mysql\share\charsets\ )
und hier mit:
Array ( [Variable_name] => character_set_client [Value] => utf8 ) Array ( [Variable_name] => character_set_connection [Value] => utf8 ) Array ( [Variable_name] => character_set_database [Value] => utf8 ) Array ( [Variable_name] => character_set_filesystem [Value] => binary ) Array ( [Variable_name] => character_set_results [Value] => utf8 ) Array ( [Variable_name] => character_set_server [Value] => latin1 ) Array ( [Variable_name] => character_set_system [Value] => utf8 ) Array ( [Variable_name] => character_sets_dir [Value] => c:\xampp\mysql\share\charsets\ )
Ein die() direkt hinter diversen Query-Funktionen hat nichts gebracht. Ich habe bisher wohl nicht die richtige gefunden.
Tach!
Gute Idee... hier schonmal die Zeilen von der Ausgabe direkt hinter dem Connect:
Zuerst ohne mysqli_set_charset utf8:
[latin1]
und hier mit:
[utf8]
Nun, dass nach einem mysqli_set_charset('utf8') UTF-8 angezeigt wird, ist nicht verwunderlich. Das bringt uns nicht weiter. Die Unklarheit ist ja, dass du trotz Latin1 richtige Ergebnisse in deine UTF-8-Anzeige bekommst. Um das zu klären, ist nicht die Situation direkt nach einer wissentlich herbeigeführten Änderung interessant, sondern das was ohne eine solche abläuft. Der erste Test nach dem Verbindungsaufbau, der Latin1 bestätigt hat, war schon gut. Nun aber füg bitte die Test-Abfrage (ohne mysqli_set_charset()) vor einer Query ein, von der du weißt, dass das Ergebnis richtig angezeigt wird. Danach bitte das Ergebnis abfangen und mit urlencode() untersuchen.
dedlfix.
Guten Morgen,
Nun aber füg bitte die Test-Abfrage (ohne mysqli_set_charset()) vor einer Query ein, von der du weißt, dass das Ergebnis richtig angezeigt wird. Danach bitte das Ergebnis abfangen und mit urlencode() untersuchen.
so ziemlich unmittelbar vor der Query siehts ziemlich gleich aus:
Array ( [Variable_name] => character_set_client [Value] => latin1 ) Array ( [Variable_name] => character_set_connection [Value] => latin1 ) Array ( [Variable_name] => character_set_database [Value] => utf8 ) Array ( [Variable_name] => character_set_filesystem [Value] => binary ) Array ( [Variable_name] => character_set_results [Value] => latin1 ) Array ( [Variable_name] => character_set_server [Value] => latin1 ) Array ( [Variable_name] => character_set_system [Value] => utf8 ) Array ( [Variable_name] => character_sets_dir [Value] => c:\xampp\mysql\share\charsets\ )
Ein urlencode() des Ergebnis zeigt bei einem Begriff mit Umlaut:
Eigene+Eintr%C3%A4ge
%C3%A4 = ä und wird korrekt angezeigt.
Unmittelbar vor der Query mit dem fehlerhaften Umlaut (wie erwartet identisch):
Array ( [Variable_name] => character_set_client [Value] => latin1 ) Array ( [Variable_name] => character_set_connection [Value] => latin1 ) Array ( [Variable_name] => character_set_database [Value] => utf8 ) Array ( [Variable_name] => character_set_filesystem [Value] => binary ) Array ( [Variable_name] => character_set_results [Value] => latin1 ) Array ( [Variable_name] => character_set_server [Value] => latin1 ) Array ( [Variable_name] => character_set_system [Value] => utf8 ) Array ( [Variable_name] => character_sets_dir [Value] => c:\xampp\mysql\share\charsets\ )
Und der urlencode() des Ergebnis mit Begriff mit einem fehlerhaften Umlaut:
B%E4rbel
%E4 = soll ä sein und wird nicht korrekt angezeigt.
Hilft das weiter?
Tach!
so ziemlich unmittelbar vor der Query siehts ziemlich gleich aus:
Ich gehe also mal davon aus, dass nirgendwo ein verstecktes mysql(i)_set_charset('utf8') drinsteckt.
[...] character_set_results => latin1 [...]
Ein urlencode() des Ergebnis zeigt bei einem Begriff mit Umlaut:
Eigene+Eintr%C3%A4ge
Da ist ein Fehler im System. Wenn auf der Verbindung Latin1 erwartet wird, aber UTF-8 kommt, sind deine Daten im DBMS falsch drin. Da darf der phpMyAdmin eigentlich auch keine Umlaute richtig anzeigen.
%C3%A4 = ä und wird korrekt angezeigt.
Du hast hier ja auch UTF-8 vorliegen, obwohl das DBMS aus seiner Sicht Latin1 geliefert hat.
Unmittelbar vor der Query mit dem fehlerhaften Umlaut (wie erwartet identisch):
[...] character_set_results => latin1 [...]
Und der urlencode() des Ergebnis mit Begriff mit einem fehlerhaften Umlaut:
B%E4rbel
Hier kommt korrekt Latin1 aus dem DBMS, du reichst das aber als UTF-8 an den Browser weiter und
%E4 = soll ä sein und wird nicht korrekt angezeigt.
da es keine korrekte UTF-8-Sequenz ist, bekommst du da das � zu sehen.
Mein Fazit: Deine neue Anwendung redet die ganze Zeit UTF-8 mit dem DBMS, aber das denkt, es sei Latin1. So herum sieht alles problemlos funktionierend aus. Da steckt der Fehler. Wenn dann jemand daherkommt. An deiner Aussage, der PMA zeige alles richtig an, habe ich meine Zweifel.
dedlfix.
Da ist ein Fehler im System. Wenn auf der Verbindung Latin1 erwartet wird, aber UTF-8 kommt, sind deine Daten im DBMS falsch drin. Da darf der phpMyAdmin eigentlich auch keine Umlaute richtig anzeigen.
Ich glaube, wir kommen der Sache jetzt etwas näher, denn ich habe jetzt wiederholt nachgeschaut, dass er die sowohl die tatsächliche Tabelle in latin1 als auch die View korrekt anzeigt.
Aber der phpmyadmin zeigt nicht die Werte der anderen Tabellen korrekt an.
So wird z.B. Mindesthöhe anstatt Mindesthöhe angezeigt.
Ich habe immer nur auf die View geschaut und die wurde vom phpmyadmin (jetzt zwangsläufig) korrekt angezeigt.
Mein Fazit: Deine neue Anwendung redet die ganze Zeit UTF-8 mit dem DBMS, aber das denkt, es sei Latin1. So herum sieht alles problemlos funktionierend aus. Da steckt der Fehler. Wenn dann jemand daherkommt. An deiner Aussage, der PMA zeige alles richtig an, habe ich meine Zweifel.
Das bedeutet jetzt, dass alle Tabellen in dern neuen DB in UTF8 angelegt sind, die View aber beim Erstellen dennoch wieder in Latin1 erstellt wurde?
Das würde mir erklären, dass alle Tabellen der alten DB und die neue View in der neuen DB bom phpmyadmin korrekt angezeigt werden.
Die Lösung wäre, dass ich beim Erstellen der View sicherstelle, dass diese in UTF8 angelegt wird?
Die Lösung wäre, dass ich beim Erstellen der View sicherstelle, dass diese in UTF8 angelegt wird?
Ich habe es versucht mit
SET NAMES 'utf8';
set character_set_database=utf8;
set character_set_server=utf8;
create or replace view v_imported_users as
SELECT a.idnr as UserID,
a.loginname as UserName,
a.passwort as Password,
convert(b.name using utf8) collate utf8_general_ci as Name,
convert(b.vorname using utf8) collate utf8_general_ci as Surname,
b.email as email,
1 AS group_id, 'nophoto.jpg' as user_photo
FROM DB2.logins as a left join DB2.employees as b on a.loginname = b.pnr
where b.sichtbar <> 'N' AND b.kst <> ''
Aber im phpmyadmin werden die Werte noch immer korrekt angezeigt und auf den neuen Seiten weiterhin falsch.
Hallo
Die Lösung wäre, dass ich beim Erstellen der View sicherstelle, dass diese in UTF8 angelegt wird?
Ich habe es versucht mit
SET NAMES 'utf8';
set character_set_database=utf8;
set character_set_server=utf8;
create or replace view v_imported_users as
SELECT a.idnr as UserID,
a.loginname as UserName,
a.passwort as Password,
convert(b.name using utf8) collate utf8_general_ci as Name,
convert(b.vorname using utf8) collate utf8_general_ci as Surname,
b.email as email,
1 AS group_id, 'nophoto.jpg' as user_photo
FROM DB2.logins as a left join DB2.employees as b on a.loginname = b.pnr
where b.sichtbar <> 'N' AND b.kst <> ''
>
> Aber im phpmyadmin werden die Werte noch immer korrekt angezeigt und auf den neuen Seiten weiterhin falsch.
Die [Ausführungen in der Doku](https://dev.mysql.com/doc/refman/5.1/de/create-view.html) (ab: „Wenn Sie eine View anlegen und dann die Verarbeitungsumgebung für Anfragen ändern“) lassen mich darauf schließen, dass die Festlegung der Kodierung nicht vor der Definition des Views erfolgt, sondern erst vor seinem Aufruf.
~~~sql
-- View wurde an anderer Stelle definiert
-- Jetzt erfolgt nur Aufruf
SET NAMES 'utf-8';
SELECT * FROM v_imported_users;
Tschö, Auge
Tach!
Ich glaube, wir kommen der Sache jetzt etwas näher, denn ich habe jetzt wiederholt nachgeschaut, dass er die sowohl die tatsächliche Tabelle in latin1 als auch die View korrekt anzeigt.
Aber der phpmyadmin zeigt nicht die Werte der anderen Tabellen korrekt an.
So wird z.B. Mindesthöhe anstatt Mindesthöhe angezeigt.
Du machst in der View irgendwas mit Konvertierung. Das wäre nicht notwendig, wenn die Daten korrekt im DBMS drin wären. Du versuchst damit nur die durch die nicht richtig ausgehandelte Verbindungskodierung kaputten Daten zu reparieren und das klappt wohl nicht in allen Situationen. Ich hab allerdings keine Erfahrung und keine Muße nachzuvollziehen, was da genau abläuft. Jedefalls ist es kaputt so wie es jetzt ist, und mein Vorachlag ist, es grundlegend zu reparieren anstatt mit expliziten Konvertierungen irgendwas richten zu wollen.
Das bedeutet jetzt, dass alle Tabellen in dern neuen DB in UTF8 angelegt sind, die View aber beim Erstellen dennoch wieder in Latin1 erstellt wurde?
Nein und nein. Die Kodierungsangabe der Felder in der neuen Tabelle mag UTF-8 sein. Der Inhalt ist es aber nicht, weil du UTF-8 als Latin1 deklariert (Default-Einstellung der Verbindung) geliefert hast. Wenn man sich die Bytes in der Tabelle anschauen könnte, müsste man doppelt kodiertes UTF-8 sehen.
Die View hat nichts mit der Zeichenkodierung zu tun. Sie ist nur ein abgespeichertes SELECT-Statement, also Code ohne irgendwelche Daten, für die eine Kodierung relevant wäre. (Sollte aber (für ein WHERE zum Beispiel) ein fester Text mit Nicht-ASCII-Zeichen im Code enthalten sein, so wird MySQL diesen gemäß der Verbindungskodierung interpretieren. Alles weitere ist für uns Außenstehende nicht weiter relevant. Wenn dieser Text beim Ausführen der View mit konkreten Daten in Feldern verglichen wird, ist es MySQLs Aufgabe, notwendige Konvertierungen vorzunehmen. - Unsere Aufgabe beim Arbeiten mit MySQL ist lediglich, die Feldkodierungen zu konfigurieren und beim Verbindungsaufbau die zu verwendende Kodierung auszuhandeln.)
Die Lösung wäre, dass ich beim Erstellen der View sicherstelle, dass diese in UTF8 angelegt wird?
Nein, die Lösung wäre, auf explizite Konvertierungen zu verzichten, die Daten in der neuen DB zu korrigieren und beim Verbindungsaufbau die gewünschte Kodierung auszuhandeln. Und das ist die, die die Anwendung benötigt, also die, mit der die Daten gesendet und erwartet werden. Die alte also Latin1, die neue UTF-8. MySQL kümmert sich selbst um die notwendigen Konvertierungen.
Mehr neues hab ich an dieser Stelle nicht zu sagen, ich wiederhole mich ja jetzt schon dauernd ;)
Das Korrigieren der Daten in der neuen DB kann wie folgt ablaufen: Einen Dump erstellen und zu diesem als Parameter mitgeben, dass er Latin1 sein soll. Am besten an der Kommandozeile, nicht mit irgendwelchen Tools. Diesen Dump unverändert nehmen und importieren, dabei aber sagen, dass er UTF-8 ist. Damit sollte sich die doppelte UTF-8-Kodierung auflösen.
dedlfix.
Hello Klaus,
würdest Du es einfach mal ausprobieren, was ich geschrieben habe, auch wenn alle Anderen kreischen, dass das Quatsch ist?
https://forum.selfhtml.org/?t=217248&m=1491620
Baue bitte _zwei_ Verbindungen auf.
Setze für jede Verbindung das passende Character-Set
http://de3.php.net/manual/en/mysqli.set-charset.php
Nun sollten die Daten auf der einen Verbindung in der einen Codierung und auf der anderen in der anderen kommen.
Zur Anzeige hast Du eine dritte Codierung, in die du die beiden anderen (oder auch nur eine) erst umwandeln musst. Das geht dann mit
http://de3.php.net/manual/en/function.mb-convert-encoding.php
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Tach!
würdest Du es einfach mal ausprobieren, was ich geschrieben habe, auch wenn alle Anderen kreischen, dass das Quatsch ist?
So viel Quatsch ist es gar nicht.
Baue bitte _zwei_ Verbindungen auf.
Hat er ja schon, viele Verbindungen im Altbestand und das neue Modul hat seine eigene(n).
Setze für jede Verbindung das passende Character-Set
http://de3.php.net/manual/en/mysqli.set-charset.php
"Passend" kann hier nur heißen, passend zur Kodierung wie sie der Client haben möchte und sendet. Zur Tabelle passend und dann auf der Verbindung was anderes sprechen, wäre allerdings Quatsch.
Nun sollten die Daten auf der einen Verbindung in der einen Codierung und auf der anderen in der anderen kommen.
Vorausgesetzt, die Daten sind intern richtig angekommen, so dass sie MySQL zur jeweils gewünschten (Verbindungs-)Kodierung richtig umkodieren kann. Dieses selbständige Umkodieren lässt sich auch nicht ausschalten (oder wegignorieren). Man muss das schon richtig machen, sonst gehen Daten verloren. Ohne diese Arbeitsweise zu berücksichtigen einfach irgendwas probieren, wird nicht in jedem Fall von Erfolg gekrönt sein.
Zur Anzeige hast Du eine dritte Codierung, in die du die beiden anderen (oder auch nur eine) erst umwandeln musst. Das geht dann mit
http://de3.php.net/manual/en/function.mb-convert-encoding.php
Kann man machen. Die Umkodierung kann aber auch MySQL selbst vornehmen.
dedlfix.
Hello,
Zur Anzeige hast Du eine dritte Codierung, in die du die beiden anderen (oder auch nur eine) erst umwandeln musst. Das geht dann mit
http://de3.php.net/manual/en/function.mb-convert-encoding.phpKann man machen. Die Umkodierung kann aber auch MySQL selbst vornehmen.
Das war ja die Frage (die ich im Hinterkopf hatte), ob MySQL das auch wirklich tut oder nach außen nur die zur Tabelle/Datenbank passende Codierung liefern möchte. DEN Verdacht habe ich nämlich noch. Ich habe hier auch Umstellungen (Migrationen von Daten) vorgenommen und die haben nur so geklappt, wie ich es beschrieben habe.
Vielleicht finde ich ja nun noch meinen Fehler, wäre mir auch recht, obwohl mein Datenquark fertig ist. Aber es kommt bestimmt ein nächstes Mal :-O
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Tach!
Kann man machen. Die Umkodierung kann aber auch MySQL selbst vornehmen.
Das war ja die Frage (die ich im Hinterkopf hatte), ob MySQL das auch wirklich tut oder nach außen nur die zur Tabelle/Datenbank passende Codierung liefern möchte. DEN Verdacht habe ich nämlich noch.
MySQL ist eine Blackbox. Was es wirklich intern tut, kann man teilweise nur durch Versuche nachweisen. Dabei muss man aber beachten, dass die Umkodierungen
Es ist allerdings beschrieben, wie MySQL mit den ankommenden Daten der Verbindung umgeht und mit Abfrageergebnissen. Der Teil zwischen Interpretation und Schreiben in Felder sowie Auslesen und der Stelle an der character_set_results berücksichtigt wird, fehlt allerdings. Das ist der Teil, an dem ich immer behaupte, dass die Werte zwischen der Vebindungskodierung und der Feldkodierung umkodiert wird. Diese Behauptung beruht aber auf einem Versuch, den ich vor langer Zeit unternahm. Er ist auch hier im Achiv irgendwo zu finden. Seitdem hat sich in MySQL nichts diesbezügliches verändert, so dass die Testergebnisse immer noch gelten. Meine Behauptung stütze ich auf die prinzipbedingten verlustbehafteten Umkodierfehler, die sich dann nachweisen lassen. Zum Beispiel gehen Zeichen verloren, wenn man Nicht-Latin1-Zeichen auf einer UTF-8-ausgehandelten Verbindung sendet und diese in einem Latin1-Feld abzulegen versucht. Die werden dann zum Fragezeichen 0x3F (meiner Erinnerung nach). Latin1 hat ja kein zu � äquivalentes Zeichen. Dieses Fragzeichen lässt sich nicht mehr rückwärts zum eigentlichen Zeichen umwandeln. Es wird auch weder beim Umkodieren von UTF-8 nach Latin1 noch andersrum verändert, so dass es beim Auslesen unverändert bleibt, egal welche Verbindungskodierung man wählt. Das nehme ich als Indiz, dass hinzu umkodiert wird. Beim Auslesen kann man das auch mit einem passenden Versuch in ähnlicher Form nachweisen, aber das spar ich mir jetzt.
dedlfix.
Tach!
Oder ist die einzige Möglichkeit, die Kollation der 2. DB auch auf UTF8 zu wechseln?
Du hast nicht geschrieben, welche Kodierung du auf der Verbindung zu MySQL verwendest. Vermutlich die konfigurierte und die weicht wohl von deiner erwarteten ab. Siehe http://wiki.selfhtml.org/wiki/Themen:Zeichencodierung/MySQL
(Ist das eigentlich unproblematisch für den Inhalt, wenn ich per Script die gesamte DB mit allen Tabellen und deren Felder auf UTF8 ändere?)
Du kannst die Kodierung jederzeit mit den dokumentierten ALTER-TABLE-Statements ändern. Die Daten werden dabei intern umkodiert. Und das funktioniert auch problemlos, solange der Inhalt mit der Kodierungsangabe übereinstimmt. Wenn du allerdings Daten in einer anderen Kodierung hingesendet hast, als MySQL auf der Client-Verbindung erwartet hat, sind fehlerhafte Daten im System. Prüfen kann man das nicht direkt, da die Tabellen Black-Boxen darstellen. Man braucht dazu ein System, das sie Zeichenkodierungsangaben richtig setzt und dann sollten die Daten richtig zu sehen sein. Sind sie es dann nicht, sind sie fehlerhaft im System. Man kann zu dieser Prüfung den phpMyAdmin verwenden.
dedlfix.
Hallo
Du kannst die Kodierung jederzeit mit den dokumentierten ALTER-TABLE-Statements ändern. Die Daten werden dabei intern umkodiert. Und das funktioniert auch problemlos, solange der Inhalt mit der Kodierungsangabe übereinstimmt.
Das ist für mich jetzt verwirrend. Gilt der letzte Satz, solange die vorhandenen Inhalte mit der *alten* oder mit der *neuen* Kodierung abgelegt wurden?
Ich meine, Kollation hin oder her, typischerweise werden, gerade in kleinen MySQL-gestützten Webanwendungen, die Daten in der Standardkodierung der DB abgelegt und das ist latin1_swedish oder bestenfalls latin1_general. In dieser Kodierung liegen die Texte dann in der Datenbank. Wenn nun z.B. UTF-8 für die Felder vorgegeben wird und die vorhandenen Inhalte umgerechnet werden, kommt doch schon hier Murks raus, oder? Wenn dann noch die Verbindung auf UTF-8 setzt, kann doch auch hier nur noch Murks rauskommen (quasi Murks²).
Zusammenfassung: es ist verwirrend.
Tschö, Auge
Tach!
Du kannst die Kodierung jederzeit mit den dokumentierten ALTER-TABLE-Statements ändern. Die Daten werden dabei intern umkodiert. Und das funktioniert auch problemlos, solange der Inhalt mit der Kodierungsangabe übereinstimmt.
Das ist für mich jetzt verwirrend. Gilt der letzte Satz, solange die vorhandenen Inhalte mit der *alten* oder mit der *neuen* Kodierung abgelegt wurden?
Die Kodierung der Felder spielt beim Punkt korrekter Speicherung keine Rolle, solange die Anwendungen auf der Verbindung aushandeln, welche Kodierung sie sprechen und dies dann auch korrekt tun. Alternativ können sie auch die Default-Verbindungskodierung verwenden. MySQL nimmt nun gegebenenfalls Umkodierungen zwischen der Verbindungskodierung und der Feldkodierung vor - sowohl reinzu als auch rauszu. Solange die Verbindungskodierung eingehalten wird, gibt es prinzipbedingt Datenverlust nur wenn von einem "größeren" in eine "kleineren" Zeichensatz gewechselt wird. Also wenn UTF-8 auf der Verbindung gesprochen wird (Zeichensatz ist dann Unicode) und die Felder nur auf Latin1 (Zeichensatz ist hier gleich Zeichenkodierung) stehen, gehen alle Nicht-Latin1-Zeichen flöten. Und beim Auslesen wenn die Felder UTF-8 sind, beim Beschreiben zwar alles gepasst hat, aber beim Auslesen die Verbindungskodierung auf Latin1 steht.
Ich meine, Kollation hin oder her, typischerweise werden, gerade in kleinen MySQL-gestützten Webanwendungen, die Daten in der Standardkodierung der DB abgelegt und das ist latin1_swedish oder bestenfalls latin1_general.
Kollation ist nicht Kodierung. Latin1 ist Latin1 (Kodierung), ob Schwedisch oder anderswie sortiert und verglichen wird (Kollation), spielt für die Kodierung keine Rolle.
In dieser Kodierung liegen die Texte dann in der Datenbank. Wenn nun z.B. UTF-8 für die Felder vorgegeben wird und die vorhandenen Inhalte umgerechnet werden, kommt doch schon hier Murks raus, oder?
Nur wenn man es falsch macht. Was MySQL intern umkodiert, muss einen nicht direkt interessieren. Wichtig ist die korrekt ausgehandelte Verbindungskodierung. Und dass die Kodierung der Felder alle Zeichen darstellen kann.
Wenn dann noch die Verbindung auf UTF-8 setzt, kann doch auch hier nur noch Murks rauskommen (quasi Murks²).
Also wenn Latin1 auf der Verbindung ausgehandelt wird (oder per Default so steht) und man sendet stattdessen dann UTF-8, ist das erstmal scheinbar kein Problem, solange beim Auslesen derselbe Fehler andersrum gemacht wird. Intern jedoch behandelt MySQL die Bytes der UTF-8-Sequenzen als einzelne Latin1-Zeichen. Das gibt dann Murks beim Sortieren oder Zeichenzählen und wenn man an die Feldlängenbeschränkung stößt.
dedlfix.