2010-07-22 5 views
2

J'utilise une approche générique pour recevoir une seule rangée de toute table Oracle et l'afficher dans un datagridview, en utilisant le code ci-dessous. Mais, si la table contient une colonne de type float et que la valeur a un grand nombre de décimales, j'obtiens "Opération arithmétique entraînant un débordement" à la ligne: MyReader.GetValues ​​(objCells);En C#, comment gérer les types Oracle Float? erreur de réception « opération arithmétique a donné lieu à un débordement »

  oCmd.CommandText = "OTCMIADM.OTCMI_GUI.GET_ROW"; 
      oCmd.CommandType = CommandType.StoredProcedure; 
      oCmd.Parameters.Add("PI_TABLE_NAME", OracleDbType.Varchar2, 40).Value = cmbStagingTables.SelectedItem; 
      oCmd.Parameters.Add("PI_ROWID", OracleDbType.Varchar2, 40).Value = txtRowID.Text; 
      oCmd.Parameters.Add(new OracleParameter("PIO_CURSOR", OracleDbType.RefCursor)).Direction = ParameterDirection.Output; 

      oCmd.ExecuteNonQuery(); 

      // clear the datagrid in preperation for loading 
      dgvStagingTable.Columns.Clear(); 
      dgvStagingTable.Rows.Clear(); 

      using (OracleDataReader MyReader = oCmd.ExecuteReader()) 
      { 
       int ColumnCount = MyReader.FieldCount; 

       // add the column headers 
       DataGridViewColumn[] columns = new DataGridViewColumn[ColumnCount]; 
       for (int i = 0; i < columns.Length; ++i) 
       { 
        DataGridViewColumn column = new DataGridViewTextBoxColumn(); 
        column.FillWeight = 1; 
        column.HeaderText = MyReader.GetName(i); 
        column.Name = MyReader.GetName(i); 
        columns[i] = column; 
       } 
       dgvStagingTable.Columns.AddRange(columns); 

       // get the data and add the row 
       while (MyReader.Read()) 
       { 
        //get all row values into an array 
        object[] objCells = new object[ColumnCount]; 
        MyReader.GetValues(objCells); 
        //add array as a row to grid 
        dgvStagingTable.Rows.Add(objCells); 
       } 
      } 

La trace de pile indique: à Oracle.DataAccess.Types.DecimalConv.GetDecimal (IntPtr numCtx) à Oracle.DataAccess.Client.OracleDataReader.GetDecimal (Int32 i) à Oracle.DataAccess.Client. OracleDataReader.GetValue (Int32 i) à Oracle.DataAccess.Client.OracleDataReader.GetValues ​​(Object [] valeurs)

donc je peux voir pourquoi cela cause une erreur (il est en supposant une conversion décimal); mais comment puis-je contourner cela?

J'essayé de placer explicitement le type de la colonne avant le chargement des données avec:.

dgvStagingTable.Columns [ "de TR_THROUGHPUT_TIME_NO"] = ValueType typeof (string);

et plusieurs autres typeofs, mais rien ne fait aucune différence.

Toute aide appréciée.

Répondre

1

J'ai d'abord suggéré d'utiliser OracleDbTypeEx (http://download.oracle.com/docs/html/E15167_01/OracleParameterClass.htm#CHDJHDGE) pour corriger cela pour vous, c'était faux, c'est donc une nouvelle suggestion.

donc ce que je faisais:

Create Table Testdecimalteable(
    Acol number(10) , 
    DecCol NUMBER(38,38) 
); 
/

Insert Into Testdecimalteable 
Select level,Level/(power(2,level)) 
    From Dual 
    Connect By Level < 100 ; 

/

Create or replace Procedure Testprocdecimal(Crs OUT Sys_Refcursor) 
AS 
Begin 
    Open Crs For 
    Select * 
     FROM Testdecimalteable ; 
END Testprocdecimal ; 

Maintenant, cela va obtenir des données connues pour être au-delà de .net.

puis le côté .net:

OracleConnection _conn = new OracleConnection(""); 
    _conn.Open(); 
    OracleCommand oCmd = new OracleCommand(); 
    oCmd.CommandText = "Testprocdecimal"; 

    oCmd.CommandType = CommandType.StoredProcedure; 
    oCmd.Connection = _conn; 

    OracleParameter crs = new OracleParameter(); 
    crs.OracleDbType = OracleDbType.RefCursor ; 
    crs.Direction = ParameterDirection.Output; 
    crs.ParameterName = "crs"; 
    oCmd.Parameters.Add(crs); 
    using (OracleDataReader MyReader = oCmd.ExecuteReader()) 
    { 
     int ColumnCount = MyReader.FieldCount; 
     // get the data and add the row 
     while (MyReader.Read()) 
     { 
      //MyReader.GetOracleValue(1).ToString() 
      Console.WriteLine(string.Format("{0}/{1}", MyReader.GetValue(0),MyReader.GetOracleValue(1).ToString() )); 


     } 
    } 

Cela convertit tout à chaîne, mais ça va marcher.

http://download-east.oracle.com/docs/html/A96160_01/features.htm#1048038

Je viens de regarder sur votre requête initiale une fois de plus, vous êtes appel à la requête deux fois:

oCmd.ExecuteNonQuery(); 
... 
using (OracleDataReader MyReader = oCmd.ExecuteReader()) 

vous n'avez pas besoin ExecuteNonQuery; le ExecuteReader exécute le sp

+0

Merci d'avoir signalé deux fois la requête en cours d'appel. Et votre solution proposée a fonctionné; J'ai simplement utilisé le .GetOracleValue (i) .ToString() pour influer sur le tableau avant de l'ajouter à datagridview, fonctionne un régal !! Merci encore D. – ValiantBoy

Questions connexes