178

I have a SQL Server 2008 database and I am working on it in the backend. I am working on asp.net/C#

SqlDataReader rdr = cmd.ExecuteReader();  
while (rdr.Read())  
{              
   //how do I read strings here????  
}  

I know that the reader has values. My SQL command is to select just 1 column from a table. The column contains strings ONLY. I want to read the strings (rows) in the reader one by one. How do I do this?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
zack
  • 7,115
  • 14
  • 53
  • 63

13 Answers13

172
using(SqlDataReader rdr = cmd.ExecuteReader())
{
    while (rdr.Read())
    {
        var myString = rdr.GetString(0); //The 0 stands for "the 0'th column", so the first column of the result.
        // Do somthing with this rows string, for example to put them in to a list
        listDeclaredElsewhere.Add(myString);
    }
}
Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
127
string col1Value = rdr["ColumnOneName"].ToString();

or

string col1Value = rdr[0].ToString();

These are objects, so you need to either cast them or .ToString().

SharpC
  • 6,974
  • 4
  • 45
  • 40
Mark Avenius
  • 13,679
  • 6
  • 42
  • 50
  • 3
    the [] operator returns a object, you will need to cast it as a string. – Scott Chamberlain Oct 25 '10 at 19:34
  • If you use indexes like reader.GetString(0) will it use the first column you selected in your query or the firstt column on the table. I have a table with 3 columns in order: ID, Dir, Email. My command selects dir and email. Will reader.GetStrting(0) retrieve dir or ID? Are the indexes based off the table itself on SQL Server or off the query you executed to select columns from a table? – ss7 Jun 05 '15 at 06:50
  • 1
    @shenk The indexes are based off the order of your select parameters. Either way, you are better off using the column names or aliases (i.e. rdr["ID"] as opposed to rdr[0]) – Mark Avenius Jun 05 '15 at 12:46
  • 1
    @MarkAvenius it used to be that indexing via numeric ordinals gained a performance improvement over column names/aliases - not sure if that's still the case – BaltoStar Jul 31 '15 at 01:50
  • 4
    @BaltoStar that is interesting; I wasn't aware of that. However, depending on the difference in performance (especially compared to pushing data over the wire, based on your application) I would generally say that the readability and maintainability of seeing the column names would trump any marginal improvement in performance. Thanks! – Mark Avenius Jul 31 '15 at 12:30
  • @MarkAvenius back in the early days of .NET people would benchmark and find using numeric ordinals gave huge performance gains (50%+) and all fast db-access code would use that trick. But over the years Microsoft may have improved the algorithms - I haven't looked at any recent benchmarks. – BaltoStar Jul 31 '15 at 16:21
37

Put the name of the column begin returned from the database where "ColumnName" is. If it is a string, you can use .ToString(). If it is another type, you need to convert it using System.Convert.

SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
    string column = rdr["ColumnName"].ToString();
    int columnValue = Convert.ToInt32(rdr["ColumnName"]);
}
Martin
  • 11,031
  • 8
  • 50
  • 77
25
while(rdr.Read())
{
   string col=rdr["colName"].ToString();
}

it wil work

Mohini Mhetre
  • 912
  • 10
  • 29
21

Thought to share my helper method for those who can use it:

public static class Sql
{
    public static T Read<T>(DbDataReader DataReader, string FieldName)
    {
        int FieldIndex;
        try { FieldIndex = DataReader.GetOrdinal(FieldName); }
        catch { return default(T); }

        if (DataReader.IsDBNull(FieldIndex))
        {
            return default(T);
        }
        else
        {
            object readData = DataReader.GetValue(FieldIndex);
            if (readData is T)
            {
                return (T)readData;
            }
            else
            {
                try
                {
                    return (T)Convert.ChangeType(readData, typeof(T));
                }
                catch (InvalidCastException)
                {
                    return default(T);
                }
            }
        }
    }
}

Usage:

cmd.CommandText = @"SELECT DISTINCT [SoftwareCode00], [MachineID] 
                    FROM [CM_S01].[dbo].[INSTALLED_SOFTWARE_DATA]";
using (SqlDataReader data = cmd.ExecuteReader())
{
    while (data.Read())
    {
        usedBy.Add(
            Sql.Read<String>(data, "SoftwareCode00"), 
            Sql.Read<Int32>(data, "MachineID"));
    }
}

The helper method casts to any value you like, if it can't cast or the database value is NULL, the result will be null.

Tiele Declercq
  • 2,070
  • 2
  • 28
  • 39
  • 4
    Nice piece of code, i modified it to be an extension method and works very well `reader.GetColumn("M_ID");` – Ali Umair Jun 01 '16 at 10:57
20

For a single result:

if (reader.Read())
{
    Response.Write(reader[0].ToString());
    Response.Write(reader[1].ToString());
}

For multiple results:

while (reader.Read())
{
    Response.Write(reader[0].ToString());
    Response.Write(reader[1].ToString());
}
budi
  • 6,351
  • 10
  • 55
  • 80
Piseth Sok
  • 1,789
  • 1
  • 20
  • 24
10

I know this is kind of old but if you are reading the contents of a SqlDataReader into a class, then this will be very handy. the column names of reader and class should be same

public static List<T> Fill<T>(this SqlDataReader reader) where T : new()
        {
            List<T> res = new List<T>();
            while (reader.Read())
            {
                T t = new T();
                for (int inc = 0; inc < reader.FieldCount; inc++)
                {
                    Type type = t.GetType();
                    string name = reader.GetName(inc);
                    PropertyInfo prop = type.GetProperty(name);
                    if (prop != null)
                    {
                        if (name == prop.Name)
                        {
                            var value = reader.GetValue(inc);
                            if (value != DBNull.Value)
                            { 
                                prop.SetValue(t, Convert.ChangeType(value, prop.PropertyType), null);
                            }
                            //prop.SetValue(t, value, null);

                        }
                    }
                }
                res.Add(t);
            }
            reader.Close();

            return res;
        }
Ali Umair
  • 1,386
  • 1
  • 21
  • 42
9

I would argue against using SqlDataReader here; ADO.NET has lots of edge cases and complications, and in my experience most manually written ADO.NET code is broken in at least one way (usually subtle and contextual).

Tools exist to avoid this. For example, in the case here you want to read a column of strings. Dapper makes that completely painless:

var region = ... // some filter
var vals = connection.Query<string>(
    "select Name from Table where Region=@region", // query
    new { region } // parameters
).AsList();

Dapper here is dealing with all the parameterization, execution, and row processing - and a lot of other grungy details of ADO.NET. The <string> can be replaced with <SomeType> to materialize entire rows into objects.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
8

Actually, I figured it out myself that I could do this:

while (rdr.read())
{  
  string str = rdr.GetValue().ToString().Trim();  
}
Liam
  • 27,717
  • 28
  • 128
  • 190
zack
  • 7,115
  • 14
  • 53
  • 63
  • 1
    I don't see how this approach is more complicated than the others. `Trim()` was not mentioned in the question and so is here but not in the other answers. – jwg Mar 14 '13 at 08:37
7

In the simplest terms, if your query returns column_name and it holds a string:

while (rdr.Read())
{
    string yourString = rdr.getString("column_name")
}
Dekker500
  • 821
  • 5
  • 7
  • 1
    At present the .getXXX methods on the reader only accept an integer ordinal. – Cos Callis Dec 09 '17 at 16:50
  • I'm not sure if this someting new, but curentrly I was able to use this approach and I think is the best, because you don't need to handle typing and also can identify better the value you want to get – Ernesto Alfonso Nov 16 '22 at 09:04
6

You have to read database columnhere. You could have a look on following code snippet for implementation:

string connectionString = ConfigurationManager.ConnectionStrings["NameOfYourSqlConnectionString"].ConnectionString;
using (var _connection = new SqlConnection(connectionString))
{
    _connection.Open();

    using (SqlCommand command = new SqlCommand("SELECT SomeColumnName FROM TableName", _connection))
    {

        SqlDataReader sqlDataReader = command.ExecuteReader();
        if (sqlDataReader.HasRows)
        {
            while (sqlDataReader.Read())
            {
                string YourFirstDataBaseTableColumn = sqlDataReader["SomeColumn"].ToString(); // Remember Type Casting is required here it has to be according to database column data type
                string YourSecondDataBaseTableColumn = sqlDataReader["SomeColumn"].ToString();
                string YourThridDataBaseTableColumn = sqlDataReader["SomeColumn"].ToString();

            }
        }
        sqlDataReader.Close();
    }
    _connection.Close();
}
Md Farid Uddin Kiron
  • 16,817
  • 3
  • 17
  • 43
4

I usually read data by data reader this way. just added a small example.

string connectionString = "Data Source=DESKTOP-2EV7CF4;Initial Catalog=TestDB;User ID=sa;Password=tintin11#";
string queryString = "Select * from EMP";

using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(queryString, connection))
            {
                connection.Open();

                using (SqlDataReader reader = command.ExecuteReader())
                {
                    if (reader.HasRows)
                    {
                        while (reader.Read())
                        {
                            Console.WriteLine(String.Format("{0}, {1}", reader[0], reader[1]));
                        }
                    }
                    reader.Close();
                }
            }
Mist
  • 684
  • 9
  • 30
3

I have a helper function like:

  public static string GetString(object o)
    {
        if (o == DBNull.Value)
            return "";

        return o.ToString();
    }

then I use it to extract the string:

 tbUserName.Text = GetString(reader["UserName"]);
JBrooks
  • 9,901
  • 2
  • 28
  • 32