I am having issues with my program for work. Everything build successfully, but when I debugged, I got an index out of range exception at totalUnits = Convert.ToDouble(values[1].ToString());. The program is supposed to calculate a formula and return the value to a textbox. I'm so confused. Can someone please help me? Thank you.
Justin
Heres some of my code to look at:
private double GetRefurbRate()
{
string sql = "";
double Refurb_Rate = 0;
double totalRefurb = 0;
double totalUnits = 0;
string error_msg = "";
//Getting the value for sql for totalRefurb
sql = "SELECT COUNT(distinct rp.repair_ord) " +
"FROM " + schema + ".repair_part rp " +
"WHERE rp.repair_type = 'REFURB' and rp.created_date > '" + DateTime.Now.ToString("d-MMM-yyyy") + "' ";
while (true)
{
if (!myDb.RunSql(sql, true))
{
error_msg = "DBError for getting Refurb Rate";
break;
}
if (myDb.dbRdr.HasRows)
{
if (myDb.dbRdr.Read())
{
开发者_StackOverflow中文版 object[] values = new object[myDb.dbRdr.FieldCount];
myDb.dbRdr.GetValues(values);
Console.WriteLine(values[0].ToString());
totalRefurb = Convert.ToDouble(values[0].ToString());
//Getting the value from sql for totalUnits
sql = "SELECT count(distinct rp.repair_ord) " +
"FROM " + schema + ".repair_part rp " +
"WHERE rp.repair_type = 'REFURB' and rp.ref_desig is null and rp.created_date > '" + DateTime.Now.ToString("d-MMM-yyyy") + "' ";
while (true)
{
if (!myDb.RunSql(sql, true))
{
error_msg = "DBError for getting Refurb Rate";
break;
}
if (myDb.dbRdr.HasRows)
{
if (myDb.dbRdr.Read())
{
values = new object[myDb.dbRdr.FieldCount];
myDb.dbRdr.GetValues(values);
Console.WriteLine(values[1].ToString());
totalUnits = Convert.ToDouble(values[1].ToString());
try
{
//Formula for Refurb Rate
Refurb_Rate = totalRefurb / totalUnits * 100;
break;
}
catch (Exception e)
{
Console.WriteLine(e);
}
myDb.dbRdr.Close();
if (error_msg != String.Empty)
{
MessageBox.Show(error_msg, "Get Refurb Rate",
MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
break;
}
}
}
}
}
}
return Refurb_Rate;
}
You should make sure that values[1]
exists, and that it's convertible to double.
Also, if the object is a double, you don't need to convert it, just use a cast ((double)values[1]
or values[1] as double
).
I don't know if I am supposed to tell, but just in case, arrays are zero-based, which means that if you want to refer to the first item in the array, you should you values[0]
instead of values[1]
. sorry if that wasn't necessary.
You should also reconsider removing the while (true)
if have a simler way to do this, unless you do expect an unexpected count.
In your question, both queries return just one data field, and thus you should use values[0]
in both cases.
You should first check the length of values, insure that the index (in this case, 1) is less then the length of values.
In general, your code should be more structured and prepared to handle error conditions (such as no data)
using structured exception handling can help too. Put this whole block of code into a try...catch block.
The issue is most likely coming from a return you don't expect from your database. Where the field count is 0 and there for there is no Values[1] and you get an index exception
Based on your query:
//Getting the value from sql for totalUnits
sql = "SELECT count(distinct rp.repair_ord) " + "FROM " + schema + ".repair_part rp " +
"WHERE rp.repair_type = 'REFURB' and rp.ref_desig is null and rp.created_date > '" + DateTime.Now.ToString("d-MMM-yyyy") + "' ";
You should use values[0] instead of values[1] since this query will only return 1 column count(distinct rp.repair_ord)
. It's either this or the query is wrong and you want to return other columns.
You will want to make sure the array has that many items...
if (values.Length >= 2) myvar = values[1];
this will allow you to see that the array contains that many objects before using it.
and bear in mind that arrays start their count with object 0, so whatever object you want to access is one less than the length. you need.
it might be values.count im working from memory. let me know and i will ammend my post
精彩评论