PDA

View Full Version : Zeichenkonvertierung



KM
17-10-05, 10:44
Hallo,

mein Problem betrifft zwar nicht die iSeries direkt, aber vielleicht wäre trotzdem jemand so nett und könnte meine Frage beantworten.
Ich greife per JDBC (Microsoft JDBC Treiber) auf einen MS SQL-Server zu, um aus einem Datenbank-Feld (Typ varchar) den Wert in ein String-Feld zu übertragen. Diesen String schreibe ich dann in eine Textdatei ins IFS. Dabei werden manche Zeichen (z.B. die "Gänsefüßchen") in Fragezeichen (Hexa 3F) konvertiert. Kann mir jemand sagen woran das liegen könnte ? Muß ich bei der JDBC-Verbindung irgendwas besonderes einstellen ? Oder liegt es an dem String-Feld ? Was mache ich falsch ? Anbei noch ein bisschen Code:

public static String Beschreibung(String artnr, String sprache) {

// Variablen definieren
String beschreibung = "";

try {
// Verbindung zur SQL-Datenbank aufbauen
String sql_driver = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
String sql_url = "jdbc:microsoft:sqlserver://nestor:1433;databaseName=katalog";
String sql_user = "test";
String sql_password = "test";
Class.forName(sql_driver);
Connection sql_conn = DriverManager.getConnection(sql_url, sql_user, sql_password);

// SQL-String erstellen
String sql_qry = "SELECT at_text from tblArtikeltexte WHERE at_artnr = ? AND at_sprache = ?";

// Statement-Objekt erzeugen
PreparedStatement sql_pstmt = sql_conn.prepareStatement(sql_qry);
sql_pstmt.setString(1, artnr);
sql_pstmt.setString(2, sprache);

// SQL-Abfrage ausführen
ResultSet sql_rs = sql_pstmt.executeQuery();

// Resultset verarbeiten
while(sql_rs.next()) {
beschreibung = sql_rs.getString(1).trim();
System.out.println(beschreibung);
}

// Verbindung schließen
sql_conn.close();
}
catch(SQLException ex) {
System.err.println("SQLException: " + ex.getMessage()) ;
}
catch(Exception e) {
System.err.println("Fehler: "+e.getMessage());
}
return beschreibung;
}

Vielen Dank,
KM

Fuerchau
17-10-05, 14:30
Wo läuft denn das Programm ?
Auf der AS/400 ?
Wenn ja, stelle sicher, dass dein Java-Job zur Laufzeit auch die korrekte CCSID (z.B. 273) hat.

KM
17-10-05, 15:35
Das Programm läuft auf der iSeries und der Job läuft bereits unter 273. Das kann damit auch nichts zu tun haben, denn die meisten Zeichen sind ja korrekt. Es geht nur um ein paar einzelne Zeichen, die direkt beim Einlesen offenbar nicht interpretiert werden können und deshalb zum Fragezeichen konvertiert werden.
Es muß entweder eine Einstellung beim JDBC-Treiber sein oder vielleicht ist die Methode getString ja auch nicht dafür geeignet.

Gruß,
KM

Deficiency
17-10-05, 15:44
Das gleiche Problem habe ich auch, das der Hex-Code nicht erhalten bleibt, sondern abgeändert wird( auf mein geliebtest 3F).

Bis jetzt habe ich es nur geschafft den Hex-Code über eine JSP zu erhalten und dann den Code direkt in die DB zu schreiben.

Bei der Übergabe eines Parameters von einer HTML-Seite zu einer JSP mit Hilfe eines HTM-Form, hat HTML die "gute" Eigenschaft alle Zeichen über einem best. Hex-Wert zu codieren und somit bleibt das Zeichen interpretationsfrei (also eindeutig).

Fuerchau
17-10-05, 18:13
Wenn das Programm auf der AS/400 läuft, ist ja nicht gesagt, dass die IFS-Datei automatisch die korrekte CCSID erhält.
Über WRKLNK kann man sich die Attribute der Datei (CCSID) sowie den Inhalt auch HEX anzeigen.
Die Frage ist hier, in welchem Hex-Code die Zeichen denn in die IFS-Datei geschrieben werden. Probier das doch einfach mal mit einer konstanten Zeichenfolge aus, die alle Zeichen enthält "?ABCD!". Damit bist du sicher, was genau passiert. Vielleicht wird ja auch das "?" von der Java-Funktion als Steuerzeichen interpretiert ?

KM
18-10-05, 09:32
Ich habe jetzt herausgefunden wo der Fehler lag. Und zwar wird beim Einlesen eines Feldes des RecordSets mit der Methode getString() automatisch versucht in die Codepage der zugrundeliegenden Plattform zu konvertieren. Im vorliegenden Fall hat das Programm versucht das Feld aus der SQL-Server-Datenbank in die EBCDIC-Codepage 273 zu konvertieren, da das Java-Programm über meine iSeries-Sitzung gestartet wurde. Und da es diese Sonderzeichen in der EBCDIC-Codepage nicht gibt, wurden sie in Fragezeichen konvertiert. Als ich das Programm mal in einer Windows-Umgebung laufen ließ, wurden die Zeichen korrekt übernommen.
Jetzt habe ich das Programm so geändert, dass der neue String gleich mit der richtigen Codepage erstellt wird. Das sieht dann folgendermaßen aus:

alter Code:
beschreibung = sql_rs.getString(1).trim();

neuer Code:

byte[] ba = sql_rs.getString(1).getBytes("Cp1252");
beschreibung = new String(ba);

Damit funktioniert's jetzt auch auf der iSeries. Tja, das sind halt so die Anfängerfehler. Nur drauf kommen muß man erst mal :-)

Gruß,
KM