2010-09-22 10 views
0

J'utilise ODP.NET pour accéder à Oracle DB à partir de C# .NET. S'il vous plaît voir le code suivant:Stockage de la double valeur .NET dans Oracle DB

OracleConnection con = new OracleConnection(); 
    con.ConnectionString = "User Id=user;Password=pass;Data Source=localhost/orcl"; 
    con.Open(); 

    /* create table */ 
    DbCommand command = con.CreateCommand(); 
    command.CommandType = CommandType.Text; 

    try 
    { 
    command.CommandText = "DROP TABLE TEST"; 
    command.ExecuteNonQuery(); 
    } 
    catch 
    { 
    } 

    //command.CommandText = "CREATE TABLE TEST (VALUE BINARY_DOUBLE)"; 
    command.CommandText = "CREATE TABLE TEST (VALUE FLOAT(126))"; 
    command.ExecuteNonQuery(); 

    /* now insert something */ 
    double val = 0.8414709848078965; 
    command.CommandText = "INSERT INTO TEST VALUES (" + val.ToString(System.Globalization.CultureInfo.InvariantCulture) + ")"; 
    command.ExecuteNonQuery(); 

    /* and now read inserted value */ 
    command.CommandText = "SELECT * FROM TEST"; 
    DbDataReader reader = command.ExecuteReader(); 

    reader.Read(); 
    double res = (double) (decimal)reader[0]; 

    Console.WriteLine("Inserted " + val + " selected " + res); 

La sortie de c'est toujours: Inséré 0,841470984807897 sélectionné 0,841470984807897

Mais en regardant les valeurs des variables sous débogueur val == 0.8414709848078965 res == 0 , 841470984807897

Pourquoi res est arrondi?

J'ai regardé dans DB et il y a une valeur arrondie enregistrée.

D'autre part, j'ai utilisé Oracle SQL Developer pour modifier cette valeur, et je suis capable de stocker 0.8414709848078965 dans la base de données?

J'ai essayé les types NUMBER, FLOAT (126), BINARY_DOUBLE ... toujours le même résultat.

Pourquoi l'utilisation de ODP.NET pose-t-elle un problème?

Répondre

0

Oracle a en réalité une plus grande précision pour ses nombres que .net!
J'ai essayé cela en ligne droite Oracle et cela fonctionne très bien, je recommande de changer pour utiliser un

par exemple.

-- CREATE TABLE TEST (VALUE NUMBER(38,38)); (initial test) 

INSERT INTO TEST VALUES (0.8414709848078965); 

SELECT * FROM TEST; 
VALUE     
---------------------- 
0.8414709848078965 

(recommendation) 
OracleParameter param = cmd.CreateParameter(); 
param.ParameterName = "NUMBERVALUE"; 
param.Direction = ParameterDirection.Input; 
param.OracleDbType = OracleDbType.Decimal; 
param.Value = "0.8414709848078965"; 
command.Parameters.Add(param); 
+0

Recommandation de @ tanging. En fait, je n'ai pas mentionné, que je l'utilise via l'interface ado.net, pas directement par oracle si. Il n'y a donc pas OracleDbType.Decimal. Je ne peux utiliser que DbType.Double. @using paramètres - oui, bien sûr, il est fait de cette façon dans le vrai programme. Ici, j'ai fourni seulement un exemple simplifié. Le paramètre ne résout pas le problème. –

0

OK, j'ai trouvé que cela fonctionne si le type de paramètre est OracleDbType.BinaryDouble. Mais cela fait que mon code dépend de ODP.NET. Je voulais utiliser les types ADO.NET (DbType) pour obtenir mon indépendance de code.