问题
I am developing an ATM Software as a home work in which i want to know the total amount of transaction which is processed today, for this purpose I am writting the following code
public decimal getDayTransaction(int accountid, string date, string transactiontype)
{
decimal totalamount = 0;
int i = 0;
string connectionString =
"Persist Security Info=False;User ID=sa; Password=123;Initial Catalog=ATMSoftware;Server=Bilal-PC";
try
{
using (SqlConnection connection =
new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(
"Select Amount From [Transaction] where AccountID = "
+ accountid + " AND CurrDate ='" + date
+ "' AND TransactionType = '"
+ transactiontype + "';", connection);
connection.Open();
SqlDataReader dr = command.ExecuteReader();
while (dr.Read())
{
totalamount += Convert.ToDecimal(dr.GetString(i));
i++;
}
return totalamount;
}
}
catch (Exception e)
{
return -1;
}
}
But i am getting the exception System.IndexOutOfRangeException: Index was outside the bounds of the array, although in database more than one records are available which are getting by running the same query in query window. But I don't know how to get it through coding.
Please help me.
Regards
回答1:
Thats because you're trying to read too many columns IMO.
while (dr.Read())
{
totalamount += Convert.ToDecimal(dr.GetString(i));
i++;
}
Who said there are more columns than rows? It seems like you're trying to sum a single column.
You're wasting time by selecting all rows. if you're looking for the SUM, use SUM(COLUMN1) instead
SqlCommand command = new SqlCommand("Select SUM(Amount) as sAmount From [Transaction] where AccountID = " + accountid + " AND CurrDate ='" + date+ "' AND TransactionType = '" + transactiontype + "';", connection);
connection.Open();
SqlDataReader dr = command.ExecuteReader();
while (dr.Read())
{
totalamount += Convert.ToDecimal(dr.GetString(0));
break; // Only read once, since it returns only 1 line.
}
return totalamount;
回答2:
Change the while like this.
while (dr.Read())
{
totalamount += Convert.ToDecimal(dr.GetString(0));
}
There is no need of an i there
回答3:
I think problem is in this line
totalamount += Convert.ToDecimal(dr.GetString(i));
i++;
Why are incrementing i for? you don't need to increment i
i represents the column index here. You are suppose to read from same column so you don't need to increment i.
Also it is a recommended practise to retrieve value using column name instead of index
回答4:
When you should get only one value, use the SqlCommand.ExecuteScalar, which returns a single value.
SqlCommand command = new SqlCommand("Select SUM(Amount) as TotalAmount From [Transaction] where AccountID = " + accountid + " AND CurrDate ='" + date + "' AND TransactionType = '" + transactiontype + "';", connection);
connection.Open();
decimal totalAmount = (decimal)command.ExecuteScalar();
To avoid SQL injection attacks, consider to use parameterized commands. You can find information about Execute.Scalar and Parametrized command example in the MSDN Documentation for SqlCommand.
来源:https://stackoverflow.com/questions/8693044/system-indexoutofrangeexception-index-was-outside-the-bounds-of-the-array