To avoid multiple queries, how about including the total in the select itself?
SELECT COUNT(*) AS TotalNORows, * FROM reports, software, platforms, versions etc
Pergunta
I am currently working on an C# project and I am trying to get the number of rows returned from MySQL Data Reader.
I know there is no direct function so I am trying to write my own. In the function, I pass it the MySQLDataReader
object and then loop through the MySQL Data Reader and increment a counter and return the value of the counter.
This then seems to lock up the program, I guess because I am Reader.read()
after I've got the count I'm already at the end. Instead I have tried creating a copy of the reader and then loop through the temp version but I get the same result.
Below is my code where I am executing the query and calling the function.
string query = "SELECT * FROM reports, software, platforms, versions "
+ "WHERE EmailVerified = @verified AND reports.SoftwareID = software.id AND reports.PlatformID = platforms.id "
+ "AND reports.VersionID = versions.id AND BugReportAcceptedNotificationSent = @notificationSent";
using (MySqlCommand cmd = new MySqlCommand(query, db.conn))
{
cmd.Parameters.AddWithValue("@verified", "1");
cmd.Parameters.AddWithValue("@notificationSent", "0");
using (MySqlDataReader reader = cmd.ExecuteReader())
{
totalEmails = HelperClass.totalRowsInMySQLDataReader(reader);
while (reader.Read())
{
currentEmailCount++;
EmailNotifications emailNotification = new EmailNotifications(reader);
emailNotification.sendNewBugReportAfterVerificationEmail(currentEmailCount, totalEmails);
}
}
}
Below is my function that gets the row count
public static int totalRowsInMySQLDataReader(MySqlDataReader reader)
{
MySqlDataReader tempReader = reader;
ILibraryInterface library = GeneralTasks.returnBitsLibrary(Configuration.databaseSettings, Configuration.engineConfig.logFile);
string methodInfo = classDetails + MethodInfo.GetCurrentMethod().Name;
try
{
int count = 0;
while (tempReader.Read())
{
count++;
}
tempReader = null;
return count;
}
catch (Exception ex)
{
string error = string.Format("Failed to get total rows in MySQL Database. Exception: {0}", ex.Message);
library.logging(methodInfo, error);
library.setAlarm(error, CommonTasks.AlarmStatus.Medium, methodInfo);
return -1;
}
}
Solução 2
To avoid multiple queries, how about including the total in the select itself?
SELECT COUNT(*) AS TotalNORows, * FROM reports, software, platforms, versions etc
Outras dicas
Make use of a DataTable
to load your results, e.g.
DataTable dt = new DataTable();
dt.Load(reader);
int numberOfResults = dt.Rows.Count;
You can then also iterate over the rows to read the values, e.g.
foreach(DataRow dr in dt.Rows)
{
var value = dr["SomeResultingColumn"]
}
The other option is to issue two separate SQL statements, however you would need to ensure both statements were enclosed within a transaction with a Serializable
isolation level, this is needed to make sure records aren't inserted between the execution of the two SQL statements.
i think without executing another command it's not possible...as there is no method available for count in reader class
you can try this... if it works..
string query = "SELECT * FROM reports, software, platforms, versions "
+ "WHERE EmailVerified=@verified AND reports.SoftwareID=software.id AND reports.PlatformID=platforms.id "
+ "AND reports.VersionID=versions.id AND BugReportAcceptedNotificationSent=@notificationSent";
using (MySqlCommand cmd = new MySqlCommand(query, db.conn))
{
cmd.Parameters.AddWithValue("@verified", "1");
cmd.Parameters.AddWithValue("@notificationSent", "0");
using (MySqlDataReader reader = cmd.ExecuteReader())
{
// create a new connection db.conn2 then
MySqlCommand cmd2 = new MySqlCommand(query, db.conn2))
cmd2.Parameters.AddWithValue("@verified", "1");
cmd2.Parameters.AddWithValue("@notificationSent", "0");
MySqlDataReader reader2 = cmd2.ExecuteReader();
int numberofrow=0;
while(reader2.Read())
numberofrow++;
//your codes......
}
Was working on the same problem. I hate having to iterate if a method is already available, but this is was the shortest bit I could come up with:
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader reader = cmd.ExecuteReader();
int rowcount = 0;
while(reader.Read()){
rowcount++;
}
First, create this class:
public static class Extensions
{
public static int Count(this MySqlDataReader dr)
{
int count = 0;
while(dr.Read())
count++;
return count;
}
}
This will implement .Count () on MySqlDataReader.
int count = reader.Count();
Exemple:
string sql= "SELECT * FROM TABLE";
MySqlCommand cmd = new MySqlCommand(sql, connection);
MySqlDataReader reader = cmd.ExecuteReader();
int count = reader.Count();
Maybe you could look things the other way around
or
Unfortunatelly solution from Jan Van @Herck will return one row only, so in case you are interested in getting all rows and their number in one select, this isn't what you need.
In that case I suggest uou to try this: select * , (select count(*) from my_table) AS numRow from my_table;
or read this: Getting total mysql results returned from query with a limit: FOUND_ROWS error
You can use follwoing SQL Query to get the total rows Count.
SELECT COUNT(*) FROM [MYTABLE]
from the Code you can use ExecuteScalar()
method to get the total number of rows returned by QUERY
.
Try This:
int GetRowsCount(MySqlCommand command)
{
int rowsCount=Convert.ToIn32(command.ExecuteScalar());
return rowsCount;
}
Use above function as below:
MySqlCommand command=new MySlCommand("Select count(*) from MyTable",connectionObj);
int totalRows = GetRowsCount(command)
OleDbDataReader dbreader = new OleDbDataReader();
int intcount = 0;
if (dbreader.HasRows == true)
{
if (dbreader.Read())
{
intcount = dbreader.RecordsAffected;
}
}
"dbreader.RecordsAffected" will give you the number rows changed,inserted or deleted by the last statement of SQL