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
[]演算子はオブジェクトを返します。オブジェクトを文字列としてキャストする必要があります。
スコットチェンバレン

reader.GetString(0)のようなインデックスを使用する場合、クエリで選択した最初の列、またはテーブルの最初の列を使用します。ID、Dir、Emailの3つの列があるテーブルがあります。私のコマンドは、dirとemailを選択します。reader.GetStrting(0)はディレクトリまたはIDを取得しますか?インデックスは、SQL Serverのテーブル自体に基づいていますか、またはテーブルから列を選択するために実行したクエリに基づいていますか?
2015年

1
@shenkインデックスは、選択したパラメーターの順序に基づいています。どちらの方法でも、列名またはエイリアス(rdr [0]ではなくrdr ["ID"])を使用したほうがよい
Mark Avenius

1
@MarkAveniusこれまでは、数値序数によるインデックス付けが列名/エイリアスよりもパフォーマンスを向上させていました-それがまだ当てはまるかどうかは
わかり

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でなければなりません
MethodMan

1
@MethodMan情報ありがとうございます。私はあなたの提案に従って私の答えを編集しました。
Mohini Mhetre

こんにちは、列ではなくオブジェクトとして行を取得するにはどうすればよいですか?たとえば、{id:1、name: 'John'}
Binsoi

以下のようなものが欲しい場合はどうしますか?if(rdr [0]){//ここで何かを行う} else if(rdr [1]){//ここで何かを行う}ブール値をキャストしようとしたが、無効なキャストエラーが発生する
Fahad

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の場合、結果はnullになります。


2
素晴らしいコード、私はそれを拡張メソッドに変更し、非常にうまく機能しましたreader.GetColumn<int>("M_ID");
Ali Umair

8

実際、私は自分でこれを実行できると考えました。

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

1
このアプローチが他のアプローチよりも複雑であることはわかりません。Trim()質問で言及されなかったので、ここにありますが、他の回答ではありませんでした。
jwg 2013年

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コードは少なくとも 1つの方法(通常は微妙で状況依存)壊れています。

これを回避するためのツールが存在します。たとえば、ここで文字列の列を読み取りたい場合です。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 2017

3

私は次のようなヘルパー関数を持っています:

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

        return o.ToString();
    }

次に、それを使用して文字列を抽出します。

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

1
DBNullはIConvertibleであり、DBNull.ToString()はstring.Emptyを返すため、標準のConvert.ToString(o)でも同じことが行われます。
nzeemin

あなたは正しいですが、私がこれを投稿したときにそれが行われたかどうかはわかりません。
JBrooks 2015

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();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.