# Zeichensatzkodierung



## Guest (3. Sep 2008)

Moin,

ich bekomme es einfach nicht hin, einen Datenbank Insert zu machen und dabei den Zeichensatz anzupassen.
Meine Umlaute und Sonderzeichen fehlen einfach.

Wa sich probiert habe ist:

"wöchentlich".getBytes( "charset" );  -- in das insert Statement

oder   String x = new String( "wöchentlich", "charset"); und dann x an das Insert Statement übergeben.
Die Sonderzeichen sind einfach  nicht da.


Könnte mir bitte jemand einen Tipp dazu geben ?


----------



## HoaX (3. Sep 2008)

wo nicht da? wie liest du die daten wieder aus?

je nach datenbank (z.B. bei mysql) sollte man checken welches encoding die verbindung/tabelle/... hat und ggf explizit angeben.


----------



## Gast (3. Sep 2008)

Naja, es steht halt kein ä, ö, ü, drin , sondern ein anderes Zeichen wie "w^chentlich ... 

Also scheint es irgendwie der falsche Ansatz zu sein.


----------



## Murray (3. Sep 2008)

Gast hat gesagt.:
			
		

> Naja, es steht halt kein ä, ö, ü, drin , sondern ein anderes Zeichen wie "w^chentlich ...


Wie stellst Du das fest? Enthalten die Strings im ResultSet auf einmal andere Zeichen, wenn die DB wieder aus einem Java-Programm ausgelesen wird? Oder prüfst Du das mit einer anderen Anwendung?


----------



## Gast (3. Sep 2008)

Ja, genau . In der eigentlichen Anwendung sind die Sonderzeichen weg. Das heißt in der GUI. Der Grund liegt in dem fehlerhaften INSERT-BEFEHL begründet, der von ausserhalb durchgeführt wird.


----------



## maki (3. Sep 2008)

Was heisst "ausserhalb"?
Sollen die Personen die "ausserhalb" sitzen und Daten in deine DB einfügen doch ihren Zeichensatz anpassen.


----------



## Gast (3. Sep 2008)

ausserhalb heißt, dass meine Programmierung nicht Teil der Software als soches ist. Es handelt sich um eine Schnittstelle. Meine Daten sehen auf meinem Rechner noch gut aus, doch in der DB, bzw. in der Applikation kommen unschöne Artefakte durch die Sonderzeichen zustande.


----------



## maki (3. Sep 2008)

Der Zeichensatz wird normalerweise beim aufbauen der Verbindng gesetzt, ist DB abhängig.... welche DB setzt du und wie Verbindest du dich dahin? (Die URL wäre interessant bzw. die properties, je nachdem was verwendet wird)

Welcher Zeichensatz ist in der Db selbst angegeben?


----------



## Landei (3. Sep 2008)

Nimmst du Sun's JdbcOdbc-Treiber? Der hat einige Macken. Zum Beispiel unterstützt er keinen Unicode zusammen mit MS Access (obwohl das MS Access selber sehr wohl kann).


----------



## Murray (3. Sep 2008)

Du willst aus von Java aus per JDBC Strings in die Datenbank schreiben, die eine andere, nicht in Java geschriebene Anwendung wieder lesen soll? Ob und ggfs. wie das geht, dürfte von der Datenbank abhängen. Das Statement enthält ja erstmal Unicode-Strings, die dann vom JDBC-Treiber irgendwie in das von der DB verwendete Format umgesetzt werden. Speichert die DB die Strings in ASCII-Form, dann muss dazu ein Encoding verwendet werden - und das kann man wohl bestenfalls mit irgendwelchen DB-spezifischen Konfigurationsmöglichkeiten beeinflussen.


----------



## Gast (3. Sep 2008)

Es ist eine Sybase Database , älteres Modell ( Sybase 4.1). als Treiber setze ich einen JTDS-Treiber ein.

http://jtds.sourceforge.net/

Leider habe ich die URL nicht im Kopf. Ich muss diese später nachreichen. Der eingesetzte Zeichensatz in der DB ist MacRoman.

Ich nutze aber nicht die API des Treibers, sondern normale Java SQl-Statements.


----------



## Murray (3. Sep 2008)

Hast Du schon versucht, in der Connection-URL die Property sendStringParametersAsUnicode=false zu setzen?

//EDIT: true ist der Default; um das Verhalten zu ändern, müsste man die Property auf false setzen (ist oben bereits geändert). Makis Vorschlag (s.u.) scheint aber das Problem zu treffen; das solltest Du zuerst versuchen.


----------



## maki (3. Sep 2008)

http://jtds.sourceforge.net/faq.html

```
jdbc:jtds:<server_type>://<server>[:<port>][/<database>][;<property>=<value>[;...]]
```



> charset (default - the character set the server was installed with)
> Very important setting, determines the byte value to character mapping for CHAR/VARCHAR/TEXT values. Applies for characters from the extended set (codes 128-255). For NCHAR/NVARCHAR/NTEXT values doesn't have any effect since these are stored using Unicode.


----------



## Guest (4. Sep 2008)

Hallo,

leider kann ich das Property nicht setzen:

Meine Fehlermeldung:  

FEHLER: SQLInvalid SQL statement or JDBC escape, terminating ']' not found.

Aber wozu die Klammer ?


Mein String sieht dann so aus:


```
db_url = prop.getPropertyValue("DB_PROTOCOL")+prop.getPropertyValue("DB_HOST")
		        +":"+ prop.getPropertyValue("DB_PORT")+"/"+prop.getPropertyValue("DB_NAME")+";"+prop.getPropertyValue("DB_PROP") ;
```

Sehr merkwürdig... 

Was mag daran falsch sein ?   --> +";"+prop.getPropertyValue("DB_PROP")


Gruß


----------



## Murray (4. Sep 2008)

Die Fehlermeldung kommt aber doch bei einem Statement - wie sieht das denn aus?


----------



## HoaX (5. Sep 2008)

und was ist der inhalt von DB_PROP?


----------



## Guest (5. Sep 2008)

Hallo,

du hast recht. da steht ja statement !! Das hab ich übersehen. Mein Statement habe ich wie folgt geändert:

Es ist eine Insert-Anweisung.

' "+pojo.getName().getBytes("x-MacRoman")  +"' ,  //  Das getBytes() ist also neu.

Nun zur Klammer : Das Ergebnis dieses Inserts, der ausgeführt wird:   

[B@b2002f   oder auch [B@2a4983  steht für Name und Straße in der Datenbank.  :? 


Hier wäre also schon einmal eine eckige Klammer, die am Ende nicht vorhanden ist. Vielleicht meckert er deswegen.
Jedoch läßt sich der Code nicht ausführen, wenn ich den Value in der Verbindung setze.



@HoaX   Meine Properties :   DB_PROP=sendStringParametersAsUnicode=false 
Anstatt das Property-Element auszulesen, habe ich auch den String mal alternativ angehängt. Hier kommt die gleiche Fehlermeldung.

Ich setze also ein ";" und das oben stehende Properties dahinter.  

DER FEHLER KOMMT ALLERDINGS AUCH, WENN ICH .getBytes("x-MacRoman") überall entferne. 

 :bahnhof: Ich weiss leider keinen Rat.


----------



## Murray (5. Sep 2008)

Das

```
pojo.getName().getBytes("x-MacRoman")
```
liefert ein byte-Array zurück (und keinen String). Verwendet man den Ausdruck innerhalb einer Konkatenation von Strings (wie Du es machst), dann wird darauf implizit die "toString"-Methode angewendet - und die liefert das von Dir beobachtete Format.

Da Du an dieser Stelle ja auch kein byte-Array brauchst: lass das getBytes überall weg (ersetze also nicht etwa getBytes("x-MacRoman") durch getBytes(), sondern lass einfach nur pojo.getName() stehen).
Sollte dann immer noch ein Fehler kommen, das ist es mit Sicherheit ein neuer.


----------



## Guest (9. Sep 2008)

Hallo,

ich muss noch einmal stören. Ich habe jetzt also die Connection mit den Properties "unicode=false" gesetzt. 
Darüber hinaus habe ich das getBytes wieder entfernt. Es lassen sich nun wieder Daten eintragen.

Leider werden die Umlaute immer noch nicht richtig dargestellt. 


Mein ö   =  wˆchentlich
Mein ü beim namen Lührmann : L∏hrmann,
------------------------------------------------------------------------------------


Im Prinzip werden die Sonderzeichen nun anders dargestellt, jedoch immer noch nicht richtig. Vielleicht sind die Properties der richtige Weg, doch ich muss irgendwie noch die Sonderseichen kodieren, damit diese im MacRoman Format dargestellt werden. 


Ihr wart bisher so hilfreich! Wie würdet ihr denn die Daten in den richtigen Zeichensatz konvertieren?


----------



## Murray (9. Sep 2008)

Hast Du es denn mit der Property charset=MacRoman schon versucht (ich meine, es muss MacRoman heissen und nicht x-MacRoman, den letzteres ist die Variante für java.nio, während die Version ohne das x für java.io und java.lang passt)?


----------



## Guest (9. Sep 2008)

Ok, habe das mal versucht:



```
db_url = prop.getPropertyValue("DB_PROTOCOL")+prop.getPropertyValue("DB_HOST")
+":"+prop.getPropertyValue("DB_PORT")+"/"+prop.getPropertyValue("DB_NAME")+";"
+prop.getPropertyValue("DB_PROP2") ;
```

+";"
+prop.getPropertyValue("DB_PROP2") ;  enstpricht diesem String: "charset=MacRoman"; 


Ich habe es auch einmal mit anderem Zeichensätzen versucht. Es kommt immer diese Fehlermeldung: 

Could not find a Java charset equivalent to DB charset MacRoman    // oder UFT-8  ; ISO-1

Der Treiber findet keine Zeichensätze.

Zum Thema charset habe ich auf der jtds Seite nur diesen Anbsatz gefunden:

charset (default - the character set the server was installed with)
    Very important setting, determines the byte value to character mapping for CHAR/VARCHAR/TEXT values. Applies for characters from the extended set (codes 128-255). For NCHAR/NVARCHAR/NTEXT values doesn't have any effect since these are stored using Unicode


Kann ich die Umlaute denn nicht einfach per Hand ändern ?



Grüße


----------



## quippy (9. Sep 2008)

Anonymous hat gesagt.:
			
		

> Kann ich die Umlaute denn nicht einfach per Hand ändern ?
> Grüße



Nein - außer, du sprichst selbst mit der Datenbank und verwendest nicht JDBC. Andernfalls übergibst Du Deine Daten als String - und der ist in Java perse in Unicode. Das ist auch OK, bedingt aber, daß der JDBC-Treiber weiß, was er mit den Daten machen muss, denn der muss nun aus Unicode die Zeichen auf die Zielplattform mappen.

Dazu mal ein kleiner Exkurs: vor Unicode (16 Bit) hat man nur 7 Bit für die Zeichendarstellung verwendet (127 bzw. mit 8Bit dann auch 255 verschiedene Zeichen), denn Platz ist teuer. Für einen Amerikaner ist das kein Problem, der hat keine Umlaute. Daraus entstanden die ersten Zeichentabellen ASCII und EBCDI. Letzterer auf Mainframes von IBM - IIRC. Später hat man die Europäischen Umlaute mit aufgenommen, als man auf 8 Bit umgestiegen war.

Zu C64 oder AMIGA Zeiten hatte man mit ASCII gut arbeiten können. Die ersten Codepages (mit denen ich rumkämpfen musste) kamen mit DOSe, als es sich auf der Welt verbreitete und man z.B. auch arabisch abbilden wollte. Aber eben immer noch mit 8 Bit. Also hat man verschiedene 8-Bit Codes entwickelt, die sich vor allem in den Sonderzeichen unterscheiden - und schließlich in ISOs definiert wurden.

Probiere doch ein paar Kombinationen beim encoding aus: X-MAC-ROMAN, MAC-ROMAN, MACROMAN oder mal ISO-8859-15 oder so was.


----------



## Guest (10. Sep 2008)

Ok. Es scheint tatsächlich so zu sein. Das Schlüsselwort heißt mac . Hier wurde tatsächlich ein Zeichensatz erkannt.

Nun kann ich jedoch, nachdem der richtige Zeichensatz gewählt wurde, keine Umlaute direkt in der Datenbank eintragen. Hier kommt nun diese Fehlermeldung:

FEHLER: SQLError converting client characters into server's character set.  Some character(s) could not be converted.

Umlaute können nicht konvertiert werden. Wäre es an dieser Stelle denn nicht doch möglich, dass ich anstelle der Umlaute das MacRoman Zeichen für den Umlaut setze ?

ö = /x80  . Ansonsten wüßte ich nicht wie ic nun die Umlaute eintragen kann  :bahnhof:


----------

