Question

I have successfully switched my project from odbc.datareader to mysql.datareader. The problem is that with the first one /odbc datareader), the AffectedRows property retrieves the number of rows correctly even when it was pure query. But it doesn work with mysql.datareader, its -1 then. So I cannot see the way how to retrieve the number of rows, i.e. "result views". EDIT: I know its forward only reader, but what I dont understand is following: If a place a breakpoint to the line DBreader=command.ExecuteRader(), I can see that DBreader has - in the result view - as many objects as rows should be. How it comes that its known just after running? Thank you

Was it helpful?

Solution

The reason DataReader doesn't contain the rowcount is that it can be very expensive to calculate. For example, say you execute a query that returns purchase orders that were entered this year and not deleted:

SELECT * FROM PurchaseOrders 
WHERE PurchaseDt > '2009-01-01'
AND IsDeleted = 0

And you use this query with a DataReader and read out the first 10 rows. SQL Server "streams" rows to the client as it requests them. Whenever you ask for another row, SQL Server will execute the next step of the query. So not even SQL Server knows about the total number of rows before you've actually read out all the rows.

OTHER TIPS

To count how many rows in a table (for instance the name is studentTable), firstly I use following SQL statement:

SELECT COUNT(*) FROM studentTable

I use that statement as the command text for the MySqlCommand object.

Then to know the value (how many rows) using an object of MySqlDataReader (for instance its name is reader) I use following code:

reader.GetString(0);

Below is the code that I use:

...            
MySqlConnection conn = new MySqlConnection(connString);
MySqlCommand command = conn.CreateCommand();
command.CommandText = "SELECT COUNT(*) FROM studentTable";
try
{
    conn.Open();
}
catch (Exception ex)
{
    label1.Content = ex.Message;
}

reader = command.ExecuteReader();
while (reader.Read())
{
    label1.Content = "";
    label1.Content = reader.GetString(0);
}

reader.Close();
conn.Close();

Below is the function that I use. Feel free to adjust it to your needs.

    /// <summary>
    /// Counts the number of rows in a given table.
    /// </summary>
    /// <param name="tableName">The name of the table to query.</param>
    /// <param name="closeConnectionWhenDone">A flag indicating whether the connection should be closed once the query is executed.</param>
    /// <returns>The number of rows in the table.</returns>
    private static int GetNumRowsInTable(string tableName, bool closeConnectionWhenDone = false)
    {
        string selectQueryString = String.Format("select 1 from {0};", tableName);
        int numRows = 0;
        CommandBehavior behavior = closeConnectionWhenDone ? CommandBehavior.CloseConnection : CommandBehavior.Default;
        using (var command = new OdbcCommand(selectQueryString, ODBCHelper.Connection))
        using (var reader = command.ExecuteReader(behavior))
        {
            while (reader.Read())
            {
                numRows++;
            }
        }

        return numRows; 
    }

Es muy simple, el reader no tiene la opción de contar cuantas filas existe, el Datatable si tiene esa opción. Entonces lo que hacemos es pasar todos los datos del Reader al Datatable y trabajamos con este (se muestra como recuperar el total de filas, y como recuperar un registro especifico).

String consulta = "SELECT * FROM xxx";
conexion.Open();
comando.CommandText = consulta;

reader = command.ExecuteReader();

DataTable dt = new DataTable();
dt.Load(reader);

int nrofilas = dt.Rows.Count;

foreach (DataRow dr in dt.Rows)
{
    var value = dr["nameField"];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top