2 Stimmen

Oracle NUMBER-Problem: Umwandlung von Decimal in Int64

Wir entwickeln eine eigenständige Anwendung, die ihre Daten in einer Datenbank speichert. Wir verwenden Dataset- und TableAdapter für die Kommunikation mit der Datenbank. Eine der grundlegenden Anforderungen ist, dass die Anwendung in der Lage sein muss, SQL Server, Oracle und MySQL zu verwenden. Zu diesem Zweck haben wir die Abfragen in den TAs herstellerunabhängig gemacht. Wir verwenden ODBC-Anbieter.

Für SQL Server und MySQL funktioniert es gut, aber mit Oracle hatten wir Probleme. Eines der Probleme, die wir nicht überwinden können, ist der Casting-Fehler von Decimal zu Int64.

Oracle-Tabellen verwenden NUMBER(38) für System-IDs (Autoinkrement-Felder), die, wie es scheint, auf Dezimalwerte abgebildet werden. Wir verwenden jedoch Int64/long in den DataSet/TAs, da SQL Server und MySQL BIGINT verwenden. (Beachten Sie, dass die DataSEt TableAdapters anfangs automatisch aus einem SQL Server-Schema generiert wurden).

Wir erhalten eine Cast-Ausnahme, wenn wir einen NUMBER-Wert von Oracle abrufen, da er ein Dezimalobjekt zurückgibt.

DbCommand getIDcmd = connection.CreateCommand();
getIDcmd.CommandText = "select LAST_ID from SEQUENCE_ID";
sequenceID = (Int64)getIDcmd.ExecuteScalar(); // we get a cast exception here returns decimal 

Bitte beachten Sie, dass wir versucht haben, die Präzisionszahl in Oracle zu verringern (z. B. NUMBER(10)), wie wir es bei anderen Forumseinträgen gesehen haben, aber ohne Erfolg.

Ist dies ein ODBC-Problem? Wenn wir zu einem anderen Anbieter wechseln, wird das Problem gelöst?

1voto

Vincent Malgrat Punkte 65127

Si sequence_id der Name Ihrer Sequenz ist, sieht Ihre Abfrage in Oracle nicht richtig aus. Sie würden die letzte angegebene ID mit einer Abfrage wie abfragen:

SELECT last_number FROM all_sequences WHERE sequence_owner=? AND sequence_name=?

Die Besetzung sollte kein Problem sein (wenn innerhalb int64 Bereich).

1voto

awe Punkte 21056

Sie könnten dies ausführen, um herauszufinden, welcher Typ tatsächlich zurückgegeben wird, und dann von dort aus weitermachen:

System.Windows.Forms.MessageBox.Show(getIDcmd.ExecuteScalar().GetType().ToString());

1voto

Mac Punkte 7951

Es scheint, als würde diese Abfrage immer einen "Dezimalwert" zurückgeben. Sie könnten dies versuchen:

sequenceID = Convert.ToInt64(getIDcmd.ExecuteScalar());

Ich glaube nicht, dass in Ihrem Fall ein Präzisionsverlust eintreten würde.

Beachten Sie, dass es immer eine gute Idee ist, die Genauigkeit Ihrer NUMMER zu verringern: Int64 Karten zu NUMBER(19) . Dies löst zwar nicht Ihr aktuelles Problem, kann aber weitere Probleme in der Zukunft verhindern. Zum Beispiel, wenn Sie eine IDataRecord einschließlich Ihrer Kennung (unter Verwendung des Microsoft Oracle-Providers), ein Aufruf an GetInt64 wird fehlschlagen, wenn Ihre Spalte definiert ist als NUMBER(38) und sind erfolgreich, wenn sie definiert sind als NUMBER(19) (auch wenn der Wert im richtigen Bereich liegt).

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