1

I am confused by the following issue;

I am trying to retrieve a record (column 'EmployeeId' (int)) using a SqlDataReader.

When I run the query directly on the server, I got the record correctly. When I run the same procedure to get another column (string) I got the record correctly.

I assume the issue is due to the fact that I try to get an int, the program skips the

while (mySqlDbDataReader.Read())

and goes directly to

catch (Exception eMsg1)
            {

Here is the full procedure

public string getUserId()
{
    //Check user details against login in Db
    //Local variables to capture values from Db
    string varId = "";

    //Connection string
    conn = sqlDbConnection.GetConnection();
    SqlCommand newCmd = conn.CreateCommand();
    newCmd.Connection = conn;
    newCmd.CommandType = CommandType.Text;

    //Query
    userCredentials connectedUser = new userCredentials();
    newCmd.CommandText = "SELECT EmployeeId FROM tblEmployees WHERE WinLogin='" + connectedUser.getWindowsLogin() + "';";

    //Connect
    newCmd.Connection = conn;
    conn.Open();

    //Utilisation du try-catch permettant de fermer la connexion même en cas de plantage
    try
    {
        SqlDataReader mySqlDbDataReader = newCmd.ExecuteReader();
        while (mySqlDbDataReader.Read())
        {
            //Tester que le résultat n’est pas NULL afin d’éviter un plantage au moment du crash
            if (mySqlDbDataReader["EmployeeId"] != System.DBNull.Value)
            {
                //Récupérer le nom à l’aide d’un cast
                varId = (string)mySqlDbDataReader["EmployeeId"];                        
            }
            else
            {
                varId = "Unknown";                       
            }
        }
    }
    catch (Exception eMsg1)
    {
        //In the event of trouble, display error msg
        //MessageBox.Show("Error while executing query: " + eMsg1.Message);
        Console.WriteLine(eMsg1);

        //Control
        MessageBox.Show("Empty");
    }
    finally
    {
        //Close DB connection
        conn.Close();
    }

    return varId;
}`

Thanks for your help!

Brice

2
  • 1
    Well if it's hitting the catch block, it's getting an exception, so what is the exception that it is raising? Commented Dec 3, 2012 at 14:28
  • 1
    FYI. You have a risky SQL injection opportunity in your code. You should strongly consider reading about SQL injection attacks and how to avoid them. Commented Dec 3, 2012 at 14:30

4 Answers 4

7

I am trying to retrieve a record (column 'EmployeeId' (int)) using a SqlDataReader.

So why are you casting to a string?

varId = (string)mySqlDbDataReader["EmployeeId"];

That's the problem. You should be casting it to an int instead, or using GetInt32:

// You don't need a local variable for this at all...
return mySqlDbDataReader.GetInt32(0);

(Here the 0 is "the ordinal of the EmployeeId column; you can use GetOrdinal to get the ordinal for a named column.)

You'll need to change your method's return type to int as well, of course - or call ToString if you really want the value as a string. (I'd strongly advise against it though.)

You should be able to see the details when you write the exception out to the console. I don't think execution is skipping the Read call at all - it's reading the result, then failing to convert the int to a string, causing an exception to be thrown.

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

3 Comments

Thank you all for your quick response ;)
You cannot pass column name in GetInt32(...) method. It only accepts The zero-based column ordinal.
@AnimalsAreNotOursToEat: Yup, I always forget that. Will edit.
1

You are casting an int to a string, which you cannot do.

// Change varId to an int and cast to an int
varId = (int)mySqlDbDataReader["EmployeeId"];

Or

// Call ToString to get the string representation of the underlying value
varId = mySqlDbDataReader["EmployeeId"].ToString();

Comments

1

Both Jons are correct. It is just that casting that appears to be raising the problem. I'd like to suggest using a Typed QueryTableAdapter for your purpose. Simply add a new DataSet to your project, right-click in the DataSet Designer and add a Query. Type your query there, introduce your variable (user name in this case I guess) and it will generate a query function in your QueryAdapter that will accept the variable from you, run the query and return EmployeeID. Moreover it will also save you from SQL injection type of things because it uses typed parameters internally.

Comments

0

Try to convert the int:

instead of

//Récupérer le nom à l’aide d’un cast
varId = (string)mySqlDbDataReader["EmployeeId"];   

use

//Récupérer le nom à l’aide d’un cast
varId = mySqlDbDataReader["EmployeeId"].ToString();   

This is of course assuming that EmployeeId is not nullable.

2 Comments

What's the difference between the two?
Hah! Copy and paste got me!

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.