Прочитайте дані з SqlDataReader


157

У мене є база даних SQL Server 2008, і я працюю над нею в сервер. Я працюю на asp.net/C#

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

Я знаю, що у читача є цінності. Моя команда SQL - вибрати лише 1 стовпець із таблиці. Колонка містить рядки ТІЛЬКИ. Я хочу прочитати рядки (рядки) у читачі по черзі. Як це зробити?

Відповіді:


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

106
string col1Value = rdr["ColumnOneName"].ToString();

або

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

Це objects, тому їх потрібно або відкинути, або .ToString().


3
оператор [] повертає об'єкт, вам потрібно буде надати його як рядок.
Скотт Чемберлен

Якщо ви використовуєте такі індекси, як читач.GetString (0), він буде використовувати перший стовпець, який ви вибрали у вашому запиті, або стовпець firstt у таблиці. У мене є таблиця з 3 стовпцями в порядку: ID, Dir, Email. Моя команда вибирає dir та email. Чи отримає читач.GetStrting (0) отримати dir або ID? Чи індекси базуються на самій таблиці на SQL сервері чи на запиті, який ви виконували для вибору стовпців із таблиці?
shenk

1
@shenk Індекси базуються на порядку обраних параметрів. Так чи інакше, вам краще використовувати назви стовпців чи псевдоніми (тобто rdr ["ID"] на відміну від rdr [0])
Марк Авениус

1
@MarkAvenius це було раніше, що індексація за допомогою числових порядків покращила ефективність щодо імен стовпців / псевдонімів - не впевнений, чи все ще так
BaltoStar

3
@BaltoStar, що цікаво; Я цього не знав. Однак, залежно від різниці в продуктивності (особливо в порівнянні з передачею даних через провід, виходячи з вашої програми), я б, як правило, сказав, що читабельність та ремонтопридатність перегляду імен стовпчиків призведе до кращого покращення продуктивності. Дякую!
Марк Авенюс

36

Покладіть ім'я стовпця, який починається повертатися з бази даних, де "ColumnName"є. Якщо це рядок, ви можете використовувати .ToString(). Якщо це інший тип, вам потрібно перетворити його за допомогою System.Convert.

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

23
while(rdr.Read())
{
   string col=rdr["colName"].ToString();
}

це буде працювати


3
toString()не вірно має бути .ToString()просто fyi
MethodMan

1
@MethodMan дякую за вашу інформацію. Я редагував свою відповідь відповідно до вашої пропозиції.
Mohini Mhetre

HI, Як я можу отримати рядок як об'єкти, а не стовпчик? Наприклад {id: 1, name: 'John'}
Binsoi

Що робити, якщо я хочу щось подібне нижче. if (rdr [0]) {// зробіть щось тут} інше if (rdr [1]) {// зробіть щось тут} я намагався передати це bool, але це дає помилку при киданні
Fahad Ejaz Butt

16

Для одного результату:

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

Для кількох результатів:

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

15

Думав поділитися своїм помічником для тих, хто може ним користуватися:

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

Використання:

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

Хелперний метод призначає будь-яке вподобане вами значення, якщо воно не може передавати або значення бази даних NULL, результат буде нульовим.


2
Хороший фрагмент коду, я змінив його на метод розширення і працює дуже добреreader.GetColumn<int>("M_ID");
Ali Umair

8

Насправді я сам зрозумів, що можу це зробити:

while (rdr.read())
{  
  string str = rdr.GetValue().ToString().Trim();  
}

1
Я не бачу, наскільки цей підхід складніший за інші. Trim()не було згадано в запитанні, і це так, але не в інших відповідях.
jwg

7

Я знаю, що це щось старе, але якщо ви читаєте вміст SqlDataReader у класі, то це буде дуже зручно. назви стовпців читача та класу повинні бути однаковими

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

На це слід рекомендувати відповідь. Дуже загальний спосіб повернення набраного списку.
kotpal

7

Я б заперечував проти використання SqlDataReaderтут; ADO.NET має безліч випадків і ускладнень, і, на мій досвід, більшість написаних вручну код ADO.NET розбивається щонайменше одним способом (як правило, тонким і контекстуальним).

Для уникнення цього існують інструменти. Наприклад, у випадку, коли ви хочете прочитати стовпчик рядків. Dapper робить це абсолютно безболісно:

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

Dapper тут має справу з усіма параметрами, виконанням та обробкою рядків - і безліччю інших шорстких деталей ADO.NET. <string>Можна замінити <SomeType>матеріалізувати цілі рядки в об'єкти.


6

Найпростіше кажучи, якщо ваш запит повертає ім'я стовпця і він містить рядок:

while (rdr.Read())
{
    string yourString = rdr.getString("column_name")
}

1
В даний час методи .getXXX зчитувача приймають лише цілу порядкову.
Cos Callis

3

У мене є помічник функції, як:

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

        return o.ToString();
    }

то я використовую його для витягування рядка:

 tbUserName.Text = GetString(reader["UserName"]);

1
Стандарт Convert.ToString (o) робить те саме, тому що DBNull є IConvertible, а DBNull.ToString () повертає string.Empty.
nzeemin

Ви маєте рацію, але я не впевнений, що це зробив, коли я розмістив це.
JBrooks

3

Я зазвичай таким чином читаю дані читачем даних. просто додав невеликий приклад.

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

1

Ви повинні read database columnтут. Ви можете подивитися наступний фрагмент коду

                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();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.