Laden...

Länderabhängige Trennzeichen

Erstellt von Endro vor 15 Jahren Letzter Beitrag vor 15 Jahren 7.777 Views
E
Endro Themenstarter:in
96 Beiträge seit 2008
vor 15 Jahren
Länderabhängige Trennzeichen

Oracle 10g - ENG
ADO.Net
C# FW 2

Hallo zusammen,

bin da auf ein Problem gestossen in Zusammenhang mit den unterschiedlichen Ländereinstellungen bezüglich den Zahlenformat (DE "," ; ENG "." als Trennzeichen)

Das Problem stellt sich folgendermassen dar. Die Software wird auf allen Kontinenten eingesetzt und somit ändert sich das Zahlenformat.

Beim abspeichern hatte ich keine Probleme Damit weil Oracle das selbstständig unwandelt ("."). Doch wenn ich nun so einen Datensatz editieren möchte wird z.B. für Deutschland auch ein 99.72 angezeigt (funktioniert). Aber wenn ich diesen Datensatz speichern möchte bekomme ich ein Problem. Sobald ich dann den . durch ein , ersteze funktioniert alles Prima.

Wie kann ich je nach land automatisch das richtige Trennzeichen anzeigen und abspeichern?

Auch würde mich interessieren wie ich ein Textfeld so einrichten kann dass nur zahlen sowie die Trennzeichen erlaubt sind.

Habe schon im Forum gesucht - bin aber bisher nicht fündig geworden.

Endro

3.511 Beiträge seit 2005
vor 15 Jahren

Wenn ihr die Zahlenwerte in den entsprechenden Datentypen speichert (INT, NUMERIC, usw...), dann spielt es doch überhaupt keine Rolle, was für eine Kultur gerade am laufen ist. Es ist ja nur ein Problem der Darstellung.

Sobald ich dann den . durch ein , ersteze funktioniert alles Prima.

Das sieht mir fast danach aus, das nicht mit Parametern gearbeitet wird. Wie genau speicherst du die Datensätze?

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

E
Endro Themenstarter:in
96 Beiträge seit 2008
vor 15 Jahren

Hi,

Danke erst mal für die schnelle Antwort.

Also den Wert des Textfeldes convertiere ich in int, double oder decimal und das direkt im SQLString.

etwa so:
string a = " insert into table Menge = '" + convert.toInt32(txtfeld.text) + "' ...;

dann wird das Komma in der Datenbank als Punkt gepeichert. Nachdem ich es wieder hole z.B. zum Editieren habe ich dann eben einen Punkt 5.5 - wenn ich diesen wiederum speichern möchte bekommen ich einen fehler.

Wo könnte sich mein Fehler befinden?

Endro

3.511 Beiträge seit 2005
vor 15 Jahren

Also den Wert des Textfeldes convertiere ich in int, double oder decimal und das direkt im SQLString.

Das ist schonmal falsch 🙂. Arbeite immer nur mit Parametern.

Also in etwa so: (für MS SQL, da ich kein Plan von Oracle habe)


string cmdText = "INSERT INTO Menge (DoubleSpalte) VALUES (@Wert)";
SqlCommand cmd = new SqlCommand(cmdText);
cmd.Parameters.AddWithValue("Wert", 32.23);
cmd.ExecuteNonQuery();

Deine Datenhaltung finde ich etwas merkwürdig. Benutzt du Businessklassen? Denn so wie es aussieht, gehst du direkt von der GUI auf die DB. Normalerweise gehört da noch was zwischen. Also eine Klasse, die die Daten hält und auch die Validierung übernimmt. Also DB -> Businessklasse -> GUI und zurück genau umgekehrt. Die GUI sollte mit der DB nicht arbeiten, bzw. diese erst gar nicht kennen.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

F
10.010 Beiträge seit 2004
vor 15 Jahren

Oracle erwartet ":" statt "@"

E
Endro Themenstarter:in
96 Beiträge seit 2008
vor 15 Jahren

Hi,

toll dass hier so schnell geantwortet wird.

Ich hab das mal ne Grundsätzliche Frage.

Was genau ist der Unterschied zwischen der übergabe der Variablen und der Übergabe mit Parametern.

Weshalb sollte durch die Übergabe mit Parametern die Ländergeschichte wegfallen?

Wäre echt klassen wenn ihr mir in dieser Beziehung auf die Sprünge helfen könntet.

Endro

3.511 Beiträge seit 2005
vor 15 Jahren

Was genau ist der Unterschied zwischen der übergabe der Variablen und der Übergabe mit Parametern.

Eine der vielen Vorteile ist unter anderem das Verhindern von "SQL Injection" (einfach mal nach suchen). Aber hier mal ein Beispiel:

Ohne Parameter


double d1 = 322.32;
int i1 = 23;
bool b1 = true;
string s1 = "Hallo Welt";

StringBuilder sb = new StringBuilder(); 
sb.AppendLine("UPDATE Tabelle SET"); // 1
sb.AppendLine("DoubleValue = " + Convert.ToString(d1) + ","); // 2
sb.AppendLine("IntValue = " + Convert.ToString(i1) + ","); // 3
sb.AppendLine("BoolValue = " + Convert.ToString(b1) + ","); // 4
sb.AppendLine("StringValue = '" + s1 + "'"); // 5

SqlCommand cmd = new SqlCommand(sb.ToString());
cmd.ExecuteNonQuery();

So, was als erstes sofort auffällt: Extrem unübersichtlich. Wobei das noch nicht mal das schlimmste ist. Der erste Fehler könnte direkt in der Zeile 2 auftreten. Bei einem englischen System, läuft es durch, denn Convert.ToString(d1) = "322.32". Der Punkt wird vom SQL Server aktzeptiert. Bei einem deutschen System ist hier sofort schluss, denn Convert.ToString(d1) = "322,32". Das Komma wird das UPDATE Statement zerstören:


UPDATE Tabelle SET
DoubleValue = 322,32 -- <- Bumm

Hier ist also die erste Falle. Es ist nicht mehr gewährleistet, das das Statement auf jedem System kulturunabhängig funktioniert.

Ebenfalls ist das Risiko in Zeile 5 ziemlich hoch, denn wenn hier ein String übergeben wird, in dem folgendes steht "Hier ist's kalt". Das SQL dazu wäre


StringValue = 'Hier ist's kalt' -- <- Bumm

Hier wird der String zerstückelt und somit das Statement ungültig.

Das ganze nochmals mit Parametern:


double d1 = 322.32;
int i1 = 23;
bool b1 = true;
string s1 = "Hallo Welt";

StringBuilder sb = new StringBuilder(); 
sb.AppendLine("UPDATE Tabelle SET"); // 1
sb.AppendLine("DoubleValue = @DoubleValue,"); // 2
sb.AppendLine("IntValue = @IntValue,"); // 3
sb.AppendLine("BoolValue = @BoolValue,"); // 4
sb.AppendLine("StringValue = @StringValue"); // 5

SqlCommand cmd = new SqlCommand(sb.ToString());
cmd.Parameters.AddWithValue("DoubleValue", d1); // 1
cmd.Parameters.AddWithValue("IntValue", d1);
cmd.Parameters.AddWithValue("BoolValue", d1);
cmd.Parameters.AddWithValue("StringValue", d1); // 5
cmd.ExecuteNonQuery();

So, hier ist gleich zu sehen das der Code wesentlich besser aussieht und strukturierter wirkt.

So, zu Zeile 2: Hier wird jetzt wirklich nur der Wert übergeben. Der SQL Server arbeitet dann auch nur intern mit dem Parameter (sowas kann man sehr schön im SQL Profiler sehen). Man muss hier also gar nicht mehr auf die Formatierung achten. Das macht der Server jetzt selber. Das Gleiche gilt für Zeile 5. Der String wird im Server autom. korrekt verarbeitet.

So, das sollte jetzt auch deine Frage

Weshalb sollte durch die Übergabe mit Parametern die Ländergeschichte wegfallen?

beantworten 🙂

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

E
Endro Themenstarter:in
96 Beiträge seit 2008
vor 15 Jahren

Hi,

super echt klasse.

finde ich super von dir dass du dir soviel mühe gemacht hast - hat mir auch wirklich weitergeholfen.

Soweit ich das verstanden habe wird mit übergabe von parametern dem datenbankserver die richtige formatierung überlassen.

Danke.

Endro

3.511 Beiträge seit 2005
vor 15 Jahren

Soweit ich das verstanden habe wird mit übergabe von parametern dem datenbankserver die richtige formatierung überlassen.

Jein 😉

Parameteresierte Abfragen laufen als Stored Procedures ab. Wenn man also ein SQL Query hat, wie z.B.


SELECT Bla FROM Blubb
WHERE SpalteA = @SpalteA -- z.B. Double mit 22.33
AND SpalteB = @SpalteB -- z.B. VarChar mit 'Hallo'

Dann wird das Query wie folgt im SQL Server abgesetzt


EXEC sp_executesql N'SELECT Bla FROM...', 
  N'@SpalteA numeric(10,2)' = 22.33,
  N'@SpalteB varchar(5)' = 'Hallo'

Dieses Query wird zum Schluss gegen den Server angesetzt. Es gibt also keine Formatierung im eigentlichen Sinne. Die Werte werden direkt im SQL verwendet. Das ist ja der große Vorteil der Parameter. Man muss sich um nichts kümmern.

Die SP sp_executesql ist im SQL Server eine sogenannte "Extended Stored Procedure". Also keine Stored Procedure im SQL Server, sondern eine Methode die aus einer DLL kommt und im Server gemapppt ist. Deswegen kann ich nicht sagen, wie es von da aus weiter geht 🙂

Ich schätze mal, bzw. ich gehe davon aus, das das Oracle entweder genau so macht, oder sehr sehr ähnlich (würde mich persönlich mal interessieren).

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)