Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I return a single value from an SqlDataReader?

Tags:

c#

.net

asp.net

I forget to return value in single tier application.

public  int Studentid()
    {
        try
        {
            SqlConnection con = new SqlConnection(connectionStr);
            SqlCommand cmd = new SqlCommand("SELECT s_id FROM student where name = + ('" + Request.QueryString.ToString() + "')", con);
            con.Open();
            SqlDataReader dr = null;
            con.Open();
            dr = cmd.ExecuteReader();
            if (dr.Read())
            {
                //Want help hear how I return value
            }

            con.Close();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
like image 475
4b0 Avatar asked Jan 02 '12 15:01

4b0


People also ask

How do I return a single value in SQL?

The Command object provides the capability to return single values using the ExecuteScalar method. The ExecuteScalar method returns, as a scalar value, the value of the first column of the first row of the result set. The following code example inserts a new value in the database using a SqlCommand.

What does SqlDataReader return?

As explained earlier, the SqlDataReader returns data via a sequential stream. To read this data, you must pull data from a table row-by-row Once a row has been read, the previous row is no longer available.

Which method returns an DataReader object?

As you've seen in the previous examples, you call the ExecuteReader method of the Command object, which returns an instance of the DataReader.

Is it necessary to manually close and dispose of SqlDataReader?

You don't need the . Close() statement in either sample: it's handled by the . Dispose() call.


2 Answers

Here is a version of your method that achieves what you're after.

public int GetStudentId()
{
    var sql = string.Format("SELECT s_id FROM student where name = '{0}'", Request.QueryString);
    using (var con = new SqlConnection(connectionStr))
    using (var cmd = new SqlCommand(sql, con))
    {
        con.Open();
        var dr = cmd.ExecuteReader();
        return dr.Read() ? return dr.GetInt32(0) : -1;
    }
}

There's no need to use try/catch when you don't do anything with the exception except re-throw (and in fact you were losing the original stack trace by using throw ex; instead of just throw;. Also, the C# using statement takes care of cleaning up your resources for you in fewer lines of code.

IMPORTANT

Passing the query string directly into SQL like that means that anyone can execute random SQL into your database, potentially deleting everything (or worse). Read up on SQL Injection.

like image 131
Drew Noakes Avatar answered Sep 22 '22 17:09

Drew Noakes


You should use using blocks, so that you are sure that the connection, command and reader are closed correctly. Then you can just return the value from inside the if statement, and doesn't have to store it in a variable until you have closed the objects.

You only have to open the connection once.

You should use parameterised queries, instead of concatenating values into the query.

public  int Studentid() {
  try {
    using (SqlConnection con = new SqlConnection(connectionStr)) {
      using (SqlCommand cmd = new SqlCommand("SELECT s_id FROM student where name = @Name", con)) {
        cmd.Parameters.Add("@Name", DbType.VarChar, 50).Value = Request.QueryString.ToString();
        con.Open();
        using (SqlDataReader dr = cmd.ExecuteReader()) {
          if (dr.Read()) {
            return dr.GetInt32(0);
          } else {
            return -1; // some value to indicate a missing record
            // or throw an exception
          }
        }
      }
    }
  } catch (Exception ex) {
    throw; // just as this, to rethrow with the stack trace intact
  }
}
like image 45
Guffa Avatar answered Sep 23 '22 17:09

Guffa