Kom ihåg mig?
Home Menu

Menu


Databas med MySQL, men med ISO som output?

 
Ämnesverktyg Visningsalternativ
Oläst 2008-12-12, 16:47 #21
Magnus_A Magnus_A är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: May 2006
Inlägg: 2 604
Magnus_A Magnus_A är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: May 2006
Inlägg: 2 604
Det som hänt här är att kodningen blivit skruvad ett steg för långt. När tecknet för å i utf8 matades in i tabellen första gången, via anslutningen latin1 (set names latin1), blev det tvåbytes som bildar å tolkade som två separata tecken, vart och ett representerat av två bytes När man kallar fram det med samma anslutning altin1, så returnerar mysql två bytes som tillsammans "råkar" bilda bokstaven å.
Ändrar man sedan anslutningen till utf8 (set names utf8) så levererar mysql helt korrekt två bytes som behövs för att rendera de två tecken som tidigare bildade bokstaven å.
Vi får alltså ut fyra bytes där vi istället bara skulle haft två, dessa kombinationer bildar inga vettiga tecken och där för ser vi vad Lindahl ser :
Citat:
Intressant, med "set names utf8" blir ordet "ingå" istället "ingÃ¥",
Det är varje fall min tolkning av vad som händer, jag tar gärna emot förslag på förbättringar

för den som vill pula lite i mysql kan roa sig med följade terminalövning:
Citat:
SET NAMES latin1;
drop table people;
CREATE TABLE people ( id int(11) unsigned NOT NULL auto_increment, name varchar(64) default NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO people VALUES
(1,'user_a'), (2,'user_å'),
(3,'user_ä');
select * from people;
SET NAMES utf8;
INSERT INTO people VALUES
(4,'user_a'),
(5,'user_å'),
(6,'user_ä');
select * from people;
alter table people engine=MyISAM default character set utf8;
ALTER TABLE people CHANGE name name BLOB;
ALTER TABLE people CHANGE name name varchar(64) CHARACTER SET utf8;
select * from people;
SET NAMES latin1;
select * from people;
Magnus_A är inte uppkopplad   Svara med citatSvara med citat
Oläst 2008-12-12, 21:55 #22
martines avatar
martine martine är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Mar 2005
Inlägg: 767
martine martine är inte uppkopplad
Mycket flitig postare
martines avatar
 
Reg.datum: Mar 2005
Inlägg: 767
Citat:
Originally posted by Magnus_A@Dec 12 2008, 17:47
Det är varje fall min tolkning av vad som händer, jag tar gärna emot förslag på förbättringar
Att vi bara orkar! :lol: Detta börjar bli lite utdraget (typiskt att man alltid låter dra sig in i sånt här…)

Okej. Som förtydligande och bevis på att det fungerar gjorde jag lite knappande och kommenterade det hela:
Kod:
CREATE TABLE t (f TEXT CHARSET latin1);
SET NAMES 'latin1';
INSERT INTO t VALUES ("åsa");
SET NAMES 'utf8';
SELECT * FROM t;

-- Ger åsa visat som utf-8, ger Ã¥sa visat som iso-8859-1
-- Den "dubbla" konverteringen sker med SET NAMES och ligger inte i databasen

DROP TABLE t;
CREATE TABLE t (f TEXT CHARSET latin1);
SET NAMES 'latin1';
INSERT INTO t VALUES ("åsa");
ALTER TABLE t MODIFY f BLOB;
ALTER TABLE t MODIFY f TEXT CHARACTER SET utf8;
SET NAMES 'utf8';
SELECT * FROM t;

-- åtger korrekt åsa visat som utf-8, ger Ã¥sa visat som iso-8859-1
-- (dvs är korrekt om filen tolkas som utf-8)

-- Samma sak med fältet som BLOB och konverteringen inte inlagd i databasen, bra för testning innan
DROP TABLE t;
CREATE TABLE t (f TEXT CHARSET latin1);
SET NAMES 'latin1';
INSERT INTO t VALUES ("åsa");
ALTER TABLE t MODIFY f BLOB;
SET NAMES 'utf8';
SELECT CONVERT(f USING utf8) FROM t;

-- Vad vi vill åstadkomma:
DROP TABLE t;
CREATE TABLE t (f TEXT CHARSET latin1);
SET NAMES 'latin1';
INSERT INTO t VALUES ("åsa");
ALTER TABLE t MODIFY f BLOB;
ALTER TABLE t MODIFY f TEXT CHARACTER SET utf8;
-- Tabellen är ändrad som ovan allt borde fungera.

-- Innan vi nu SELECT:ar så sätter NAMES till latin1 för vi vill ha ut data i iso-teckenkodning:
SET NAMES 'latin1';
SELECT * FROM t;
-- Ger Xsa (X ogiltigt unicodetecken) visat som utf-8, ger åsa visat som iso-8859-1
(Notera att de tre-fyra första raderna i exemplen bara raderar testtabellen och sedan återskapar den enligt "stoppa in uft-8 i latin1-fält"-metoden. All input var utf-8.)

Aningen oöversiktiligt men i grunden rätt enkelt:

1. Har man en tabell som egentligen är i utf8 men är deklarerad som latin1 i tabellen (gammalt rävknep för att spara utf8-data i databaser som bara kan hantera iso) så beböver man konvertera fälten enligt följande enkla kommando för varje fält (MySQL tillåter för övrigt att ändra flera kolumner i en tabell med en ALTER-sats):
Kod:
ALTER TABLE exempelfält MODIFY f BLOB;
ALTER TABLE t MODIFY exempelfält TEXT CHARACTER SET utf8;
I fall det handlar om en VARCHAR/ENUM/SET istället för TEXT så anpassas frågan för detta.

2. För att det sedan inte ska bli fel när man hämtar data så är det viktigt att man även sätter överföringsteckenkodningen (vilken är det teckensnitt man deklarerat på t.ex. hemsidan, i normalfallet utf-8) antingen i sin .ini-fil eller med sql:
Kod:
SET NAMES 'utf8'
3. För att lösa Lindahls ursprungliga problem behöver han alltså först göra ovan så att fälten är korrekt deklarerade och sedan bara använda:
Kod:
SET NAMES 'latin1';
följt av select-frågan för att få ut sin feed i iso-8859-1-form.
martine är inte uppkopplad   Svara med citatSvara med citat
Svara


Aktiva användare som för närvarande tittar på det här ämnet: 1 (0 medlemmar och 1 gäster)
 

Regler för att posta
Du får inte posta nya ämnen
Du får inte posta svar
Du får inte posta bifogade filer
Du får inte redigera dina inlägg

BB-kod är
Smilies är
[IMG]-kod är
HTML-kod är av

Forumhopp


Alla tider är GMT +2. Klockan är nu 18:20.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson
 
Copyright © 2017