4 Stimmen

Fremde Zeichen/Akzente in Sql-Abfrage

Ich verwende Java und die JdbcTemplate-Klasse von Spring, um eine SQL-Abfrage in Java zu erstellen, die eine Postgres-Datenbank abfragt. Ich habe jedoch Probleme bei der Ausführung von Abfragen, die fremde/akzentuierte Zeichen enthalten.

Zum Beispiel der (gekürzte) Code:

JdbcTemplate select = new JdbcTemplate( postgresDatabase );

String query = "SELECT id FROM province WHERE name = 'Ontario';";

Integer id = select.queryForObject( query, Integer.class );

wird die Provinz-ID abrufen, aber wenn ich stattdessen name = 'Québec' dann gibt die Abfrage keine Ergebnisse zurück (dieser Wert befindet sich in der Datenbank, das Problem ist also nicht, dass er fehlt).

Ich glaube, die Ursache des Problems ist, dass die Datenbank, die ich verwenden muss, die Standard-Client-Kodierung auf SQL_ASCII eingestellt hat, was laut este verhindert automatische Zeichensatzkonvertierungen. (Die Java-Umgebungscodierung ist auf "UTF-8" eingestellt, während mir gesagt wurde, dass die Datenbank "LATIN1" / "ISO-8859-1" verwendet)

Ich konnte die Kodierung manuell angeben, wenn die resultSets Werte mit fremden Zeichen enthielten, um ein früheres Problem ähnlicher Art zu lösen.

Ex:

String provinceName = new String ( resultSet.getBytes( "name" ), "ISO-8859-1" );

Aber jetzt, da die fremden Zeichen Teil der Abfrage selbst sind, war dieser Ansatz nicht erfolgreich. (Ich nehme an, da die Abfrage vor der Ausführung ohnehin in einem String gespeichert werden muss, verwirrt das Aufteilen in Bytes und anschließende Ändern der Kodierung die Zeichen nur noch mehr).

Gibt es eine Möglichkeit, dieses Problem zu umgehen, ohne die Eigenschaften der Datenbank zu ändern oder sie neu zu erstellen?

PostScript: Ich fand diese Funktion auf StackOverflow bei der Erstellung eines Titels, es schien nicht zu funktionieren (vielleicht habe ich es nicht richtig verwendet, aber selbst wenn es funktioniert hat, scheint es nicht die beste Lösung zu sein):

Edit: Ich habe meine eigene Antwort ausgewählt, da ich sie vorerst verwenden werde; wie jedoch in einem Kommentar unten erwähnt, bin ich gerne bereit, andere Vorschläge zu prüfen, die möglicherweise besser sind, solange ich Zugang zur Datenbank habe.

3voto

FromCanada Punkte 366

Hmm okay, nachdem ich mich durch die postgreSQL Dokumentation gequält habe, fand ich eine Lösung in der String-Funktionen und Operatoren Abschnitt.

Ich habe die convert(string bytea, src_encoding name, dest_encoding name) Funktion und konnte die Provinz-ID für Québec abrufen.

Ex.

String query = "SELECT id FROM province WHERE name = convert( 'Québec', 'UTF-8', 'ISO-8859-1' );";

3voto

Matthew Wood Punkte 14949

Wenn Sie eine Verbindung von Java mit der Kodierung UTF-8 herstellen und die Datenbank ISO-8859-1 ist, sollten Sie diesen SQL-Befehl direkt nach der ersten Verbindung mit der DB ausführen:

SET client_encoding = 'UTF8';

PostgreSQL interpretiert dann alle Eingaben als UTF-8 und konvertiert sie dann serverseitig in ISO-8859-1. Sie sollten nichts weiter tun müssen als das.

0voto

Michael Zilbermann Punkte 1350

Wenn Ihre Datenbank mit "SQL_ASCII" kodiert ist, versteht sie im Grunde nur ASCII und nichts anderes. Das bedeutet, dass das Wort "Québec" "as provided" gespeichert wurde, d.h. "as provided as a set of bytes, according to the encoding used by the tool which processed the insert or update sql order against the database at this moment". Wenn Sie also versuchen, solche Werte auszuwählen, müssen Sie die gleiche Kodierung verwenden, aber Sie müssen vorher wissen, welche es ist.

Nachdem diese erste Aufgabe erledigt ist, brauchen Sie einen Weg, um auszudrücken, dass Ihre Anfrage diese Kodierung verwenden soll.

Nehmen wir an, dass sie in der Kodierung ISO-8859-1 gespeichert wurde.

Ich bin mir nicht sicher, ob es funktioniert, aber ich würde so etwas versuchen:

String myReq = "SELECT id FROM province WHERE name = 'Québec';";
byte[] iso8859sequence = myReq.getBytes("ISO-8859-1");
String myReqAscii = new String(iso8859sequence, "US-ASCII");
Integer id = select.queryForObject( query, Integer.class );

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X