从SqlDataReader读取数据


157

我有一个SQL Server 2008数据库,并且正在后端进行处理。我正在asp.net/C#上工作

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

我知道读者有价值观。我的SQL命令是从表中仅选择1列。该列仅包含字符串。我想一一阅读阅读器中的字符串(行)。我该怎么做呢?

Answers:


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

这些是object,因此您需要强制转换或.ToString()


3
[]运算符返回一个对象,则需要将其强制转换为字符串。
Scott Chamberlain 2010年

如果使用诸如reader.GetString(0)之类的索引,它将使用您在查询中选择的第一列或表上的firstt列。我有一个按顺序包含3列的表格:ID,Dir,Email。我的命令选择目录和电子邮件。reader.GetStrting(0)是否会检索目录或ID?索引是基于SQL Server上的表本身还是基于为从表中选择列而执行的查询?
2015年

1
@shenk索引基于选择参数的顺序。无论哪种方式,最好使用列名或别名(例如rdr [“ ID”]而不是rdr [0])
Mark Avenius 2015年

1
@MarkAvenius过去是通过数字序号进行索引比列名/别名获得了性能上的改进-不确定是否仍然如此
BaltoStar

3
@BaltoStar很有趣;我没有意识到这一点。但是,根据性能的差异(特别是与根据应用程序通过网络推送数据相比),我通常会说,看到列名的可读性和可维护性将胜过性能的任何边际改进。谢谢!
Mark Avenius 2015年

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

1
@MethodMan感谢您的信息。根据您的建议,我编辑了答案。
Mohini Mhetre '16

嗨,我如何将行作为对象而不是按列?例如{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"));
    }
}

helper方法将强制转换为您喜欢的任何值,如果无法强制转换或数据库值为NULL,则结果将为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

用最简单的术语来说,如果您的查询返回column_name并且它包含一个字符串:

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();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.