Baca data dari SqlDataReader

157

Saya memiliki database SQL Server 2008 dan saya sedang mengerjakannya di backend. Saya sedang bekerja di asp.net/C#

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

Saya tahu bahwa pembaca memiliki nilai. Perintah SQL saya adalah memilih hanya 1 kolom dari sebuah tabel. Kolom HANYA berisi string. Saya ingin membaca string (baris) di pembaca satu per satu. Bagaimana saya melakukan ini?

Zack
sumber

Jawaban:

154
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
sumber
106
string col1Value = rdr["ColumnOneName"].ToString();

atau

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

Ini adalah objects, jadi Anda harus melemparkannya atau .ToString().

Mark Avenius
sumber
3
operator [] mengembalikan objek, Anda harus melemparkannya sebagai string.
Scott Chamberlain
Jika Anda menggunakan indeks seperti reader.GetString (0) apakah itu akan menggunakan kolom pertama yang Anda pilih dalam kueri Anda atau kolom firstt pada tabel. Saya memiliki tabel dengan 3 kolom dalam urutan: ID, Dir, Email. Perintah saya memilih dir dan email. Apakah reader.GetStrting (0) mengambil dir atau ID? Apakah indeks didasarkan dari tabel itu sendiri pada SQL Server atau dari kueri yang Anda jalankan untuk memilih kolom dari tabel?
shenk
1
@shenk Indeks didasarkan pada urutan parameter pilihan Anda. Either way, Anda lebih baik menggunakan nama kolom atau alias (yaitu rdr ["ID"] sebagai lawan rdr [0])
Mark Avenius
1
@MarkAvenius dulu pengindeksan melalui ordinal numerik memperoleh peningkatan kinerja atas nama kolom / alias - tidak yakin apakah itu masih terjadi
BaltoStar
3
@BaltoStar itu menarik; Saya tidak menyadarinya. Namun, tergantung pada perbedaan kinerja (terutama dibandingkan dengan mendorong data melalui kabel, berdasarkan aplikasi Anda) Saya biasanya akan mengatakan bahwa keterbacaan dan pemeliharaan melihat nama-nama kolom akan mengalahkan setiap peningkatan kecil dalam kinerja. Terima kasih!
Mark Avenius
36

Masukkan nama kolom mulai dikembalikan dari database di mana "ColumnName". Jika itu adalah string, Anda dapat menggunakan .ToString(). Jika ini tipe lain, Anda perlu mengonversinya menggunakan System.Convert.

SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
    string column = rdr["ColumnName"].ToString();
    int columnValue = Convert.ToInt32(rdr["ColumnName"]);
}
Martin
sumber
23
while(rdr.Read())
{
   string col=rdr["colName"].ToString();
}

itu akan bekerja

Mohini Mhetre
sumber
3
toString()tidak valid harus .ToString()hanya fyi
MethodMan
1
@MethodMan terima kasih atas informasi Anda. Saya mengedit jawaban saya sesuai saran Anda.
Mohini Mhetre
HI, Bagaimana cara mendapatkan baris sebagai objek dan bukan dengan kolom? Misalnya {id: 1, nama: 'John'}
Binsoi
bagaimana jika saya menginginkan sesuatu seperti di bawah ini. if (rdr [0]) {// melakukan sesuatu di sini} lain jika (rdr [1]) {// melakukan sesuatu di sini} Saya telah mencoba untuk melemparkannya bool tapi itu memberikan kesalahan cast yang invaild
Fahad Ejaz Butt
16

Untuk satu hasil:

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

Untuk beberapa hasil:

while (reader.Read())
{
    Response.Write(reader[0].ToString());
    Response.Write(reader[1].ToString());
}
Piseth Sok
sumber
15

Berpikir untuk membagikan metode penolong saya bagi mereka yang dapat menggunakannya:

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);
                }
            }
        }
    }
}

Pemakaian:

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"));
    }
}

Metode helper dilemparkan ke nilai apa pun yang Anda suka, jika tidak bisa dilemparkan atau nilai database NULL, hasilnya akan menjadi nol.

Tiele Declercq
sumber
2
Sepotong kode yang bagus, saya memodifikasinya menjadi metode ekstensi dan bekerja dengan sangat baikreader.GetColumn<int>("M_ID");
Ali Umair
8

Sebenarnya, saya tahu sendiri bahwa saya bisa melakukan ini:

while (rdr.read())
{  
  string str = rdr.GetValue().ToString().Trim();  
}
Zack
sumber
1
Saya tidak melihat bagaimana pendekatan ini lebih rumit daripada yang lain. Trim()tidak disebutkan dalam pertanyaan dan begitu juga di sini tetapi tidak dalam jawaban lainnya.
jwg
7

Saya tahu ini agak lama tetapi jika Anda membaca isi SqlDataReader ke dalam kelas, maka ini akan sangat berguna. nama kolom pembaca dan kelas harus sama

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
sumber
Ini harus menjadi jawaban yang direkomendasikan. Cara yang sangat umum untuk mengembalikan daftar yang diketik.
kotpal
7

Saya berpendapat melawan menggunakan SqlDataReaderdi sini; ADO.NET memiliki banyak kasus tepi dan komplikasi, dan menurut pengalaman saya, kode ADO.NET yang ditulis secara manual dipecah dalam setidaknya satu cara (biasanya halus dan kontekstual).

Ada alat untuk menghindari ini. Misalnya, dalam kasus di sini Anda ingin membaca kolom string. Dapper membuatnya sangat menyakitkan:

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

Dapper di sini berurusan dengan semua parameterisasi, eksekusi, dan pemrosesan baris - dan banyak detail kotor lainnya dari ADO.NET. The <string>bisa diganti dengan <SomeType>terwujud seluruh baris ke objek.

Marc Gravell
sumber
6

Dalam istilah yang paling sederhana, jika kueri Anda mengembalikan nama_kolom dan menyimpan sebuah string:

while (rdr.Read())
{
    string yourString = rdr.getString("column_name")
}
Dekker500
sumber
1
Saat ini metode .getXXX pada pembaca hanya menerima ordinal integer.
Cos Callis
3

Saya memiliki fungsi pembantu seperti:

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

        return o.ToString();
    }

maka saya menggunakannya untuk mengekstrak string:

 tbUserName.Text = GetString(reader["UserName"]);
JBrooks
sumber
1
Convert.ToString standar (o) melakukan hal yang sama, karena DBNull adalah IConvertible, dan DBNull.ToString () mengembalikan string.Empty.
nzeemin
Anda benar, tetapi saya tidak yakin apakah itu ketika saya memposting ini.
JBrooks
3

Saya biasanya membaca data oleh pembaca data dengan cara ini. baru saja menambahkan contoh kecil.

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();
                }
            }
Kabut
sumber
1

Anda harus ke read database columnsini. Anda dapat melihat potongan kode berikut

                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
sumber