Đọc dữ liệu từ SqlDataReader


157

Tôi có cơ sở dữ liệu SQL Server 2008 và tôi đang làm việc với nó trong phần phụ trợ. Tôi đang làm việc trên asp.net/C#

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

Tôi biết rằng người đọc có giá trị. Lệnh SQL của tôi là chỉ chọn 1 cột trong bảng. Cột chỉ chứa chuỗi. Tôi muốn đọc từng chuỗi (hàng) trong trình đọc từng cái một. Làm thế nào để tôi làm điều này?

Câu trả lời:


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

hoặc là

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

Đây là objects, vì vậy bạn cần phải chọn chúng hoặc .ToString().


3
toán tử [] trả về một đối tượng, bạn sẽ cần truyền nó thành một chuỗi.
Scott Chamberlain

Nếu bạn sử dụng các chỉ mục như reader.GetString (0) thì nó sẽ sử dụng cột đầu tiên bạn chọn trong truy vấn của bạn hoặc cột đầu tiên trên bảng. Tôi có một bảng có 3 cột theo thứ tự: ID, Dir, Email. Lệnh của tôi chọn dir và email. Người đọc sẽ đọc.GetStrting (0) lấy dir hoặc ID? Các chỉ mục dựa trên chính bảng trên SQL Server hay tắt truy vấn bạn đã thực hiện để chọn các cột từ một bảng?
shenk

1
@shenk Các chỉ mục được dựa trên thứ tự các tham số đã chọn của bạn. Dù bằng cách nào, bạn tốt hơn hết là sử dụng tên cột hoặc bí danh (ví dụ: ndr ["ID"] trái ngược với ndr [0])
Đánh dấu vào

1
@MarkAvenius trước đây, việc lập chỉ mục qua các số thứ tự đã đạt được sự cải thiện hiệu suất so với tên / bí danh của cột - không chắc đó có phải là trường hợp không
BaltoStar

3
@BaltoStar thật thú vị; Tôi đã không nhận thức được điều đó. Tuy nhiên, tùy thuộc vào sự khác biệt về hiệu suất (đặc biệt là so với việc đẩy dữ liệu qua dây, dựa trên ứng dụng của bạn), tôi thường nói rằng khả năng đọc và khả năng duy trì của việc nhìn thấy các tên cột sẽ giúp cải thiện hiệu suất. Cảm ơn!
Đánh dấu Avenius

36

Đặt tên của cột bắt đầu được trả về từ cơ sở dữ liệu "ColumnName". Nếu nó là một chuỗi, bạn có thể sử dụng .ToString(). Nếu nó là một loại khác, bạn cần phải chuyển đổi nó bằng cách sử dụng 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();
}

nó sẽ làm việc


3
toString()không hợp lệ nên .ToString()chỉ là fyi
Phương thức quản lý

1
@MethodMan cảm ơn thông tin của bạn. Tôi chỉnh sửa câu trả lời của tôi theo đề nghị của bạn.
Mohini Mhetre

HI, Làm thế nào để tôi có được hàng dưới dạng đối tượng chứ không phải theo cột? Ví dụ: {id: 1, tên: 'John'}
Binsoi

Điều gì nếu tôi muốn một cái gì đó như dưới đây. if (rdr [0]) {// làm điều gì đó ở đây} khác if (rdr [1]) {// làm điều gì đó ở đây} Tôi đã cố gắng bỏ bool nhưng nó đưa ra lỗi cast invaild
Fahad Ejaz Mông

16

Đối với một kết quả duy nhất:

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

Để có nhiều kết quả:

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

15

Nghĩ đến việc chia sẻ phương pháp trợ giúp của tôi cho những người có thể sử dụng nó:

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

Sử dụng:

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

Phương thức của trình trợ giúp chuyển sang bất kỳ giá trị nào bạn muốn, nếu nó không thể truyền hoặc giá trị cơ sở dữ liệu là NULL, kết quả sẽ là null.


2
Một đoạn mã đẹp, tôi đã sửa đổi nó thành một phương thức mở rộng và hoạt động rất tốtreader.GetColumn<int>("M_ID");
Ali Umair

8

Trên thực tế, tôi đã tự tìm ra rằng tôi có thể làm điều này:

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

1
Tôi không thấy cách tiếp cận này phức tạp hơn các phương pháp khác. Trim()đã không được đề cập trong câu hỏi và ở đây nhưng không phải trong các câu trả lời khác.
jwg

7

Tôi biết điều này là cũ nhưng nếu bạn đang đọc nội dung của SqlDataReader vào một lớp, thì điều này sẽ rất tiện dụng. tên cột của người đọc và lớp phải giống nhau

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

Điều này nên được đề nghị trả lời. Cách rất chung chung để trả về một danh sách đánh máy.
kotpal

7

Tôi sẽ tranh luận chống lại việc sử dụng SqlDataReaderở đây; ADO.NET có rất nhiều trường hợp và biến chứng cạnh, và theo kinh nghiệm của tôi, hầu hết mã ADO.NET được viết thủ công bị phá vỡ theo ít nhất một cách (thường là tinh tế và theo ngữ cảnh).

Công cụ tồn tại để tránh điều này. Ví dụ, trong trường hợp ở đây bạn muốn đọc một cột chuỗi. Dapper làm cho điều đó hoàn toàn không đau:

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

Dapper ở đây đang xử lý tất cả các tham số hóa, thực thi và xử lý hàng - và rất nhiều chi tiết khác của ADO.NET. Có <string>thể được thay thế bằng <SomeType>để cụ thể hóa toàn bộ các hàng thành các đối tượng.


6

Trong các điều khoản đơn giản nhất, nếu truy vấn của bạn trả về cột_name và nó giữ một chuỗi:

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

1
Hiện tại, các phương thức .getXXX trên đầu đọc chỉ chấp nhận một số nguyên.
Cos Callis

3

Tôi có một chức năng trợ giúp như:

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

        return o.ToString();
    }

sau đó tôi sử dụng nó để trích xuất chuỗi:

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

1
Standard Convert.ToString (o) cũng làm như vậy, vì DBNull là IConvertible và DBNull.ToString () trả về chuỗi.Empty.
nzeemin

Bạn đúng, nhưng tôi không chắc nó đã làm điều đó khi tôi đăng bài này.
JBrooks

3

Tôi thường đọc dữ liệu bằng cách đọc dữ liệu theo cách này. chỉ cần thêm một ví dụ nhỏ.

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

Bạn phải read database columnở đây. Bạn có thể có một cái nhìn về đoạn mã sau

                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();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.