0

I'm doing a little app where a user enters a block of queries and then executes them.

The thing is that I want to show relevant information, like for example if he inputs something like:

SELECT * FROM server;
UPDATE server SET name = 'Kojak';

It gets:

  1. The rows selected
  2. The number of rows affected by the UPDATE

My printing loop looks like:

reader = cmd.ExecuteReader();
do
{

    while (reader.Read())
    {
        if (!(reader.RecordsAffected > 0))
        {
            for (int i = 0; i < reader.FieldCount; i++)
                host.WriteLine("Field " + i + ": " + reader[i].ToString());
        }
        else {
            host.WriteLine(reader.RecordsAffected.ToString() + " Affected rows.");
        }
    }                    
} while (reader.NextResult());
host.WriteLine("Block executed successfuly");

The thing is that I can't manage to make the difference between SELECTs and UPDATEs, because reader.Read() returns FALSE when it reaches the second query. How can I solve that and be able to get the number of affected rows when there's a UPDATE/DELETE/INSERT query ?

Thanks.

2 Answers 2

1

You can't use cmd.ExecuteReader() to execute non queries. You need to use ExecuteNonQuery().

I would imagine you will need to parse the list of SQL statements to determnine what sort of comamnd it is (e.g. SELECT or UPDATE), and call the appropriate method.

Sign up to request clarification or add additional context in comments.

2 Comments

Damn... that's what I was afraid of... Thank you David. By the way, I can still use ExecuteReader and I can also get the Affected rows value but it gets raised as long as the single statements are being executed so there's no way to know for example which query generated which number of affected rows. In JDBC this is possible.. hehe
If you're saying that ExecuteReader() will in fact execute a non-SELECT query (I've never tried it), then my answer is wrong. I guess the problem is that for non-queries, ExecuteReader() returns false, so the following line doesn't get executed. I can't help but wonder whether a different type of loop which always executes at least once would solve the problem...
0

@David: here's how I did it:

public int Execute(String block, dbStudio.components.DbsTab host)
{
    this.Connect();
    DbCommand cmd = this.dbConnection.CreateCommand();
    DbDataReader reader = null;

    cmd.CommandText = block;
    int ret = -1;

    try
    {
        long ticks = DateTime.Now.Ticks;
        reader = cmd.ExecuteReader();
        do
        {
            while (reader.Read())
            {
                String str = "";
                for (int i = 0; i < reader.FieldCount; i++)
                {
                    //host.WriteLine("Field " + i + ": " + reader[i].ToString());
                    str = str + reader[i].ToString() + "    ";
                }
                host.WriteLine(str);
            }
        } while (reader.NextResult());

        host.WriteLine("Block executed successfuly");
        host.WriteLine(reader.RecordsAffected.ToString() + " Affected rows.");
        host.WriteLine(((DateTime.Now.Ticks - ticks) / 1000).ToString() + "ms");

        ret = reader.RecordsAffected;
    }
    catch (Exception e)
    {
        host.WriteLine(e.Message);
    }
    finally
    {
        this.Disconnect();
    }
    return ret;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.