Leggi i dati da SqlDataReader


157

Ho un database SQL Server 2008 e ci sto lavorando nel backend. Sto lavorando su asp.net/C#

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

So che il lettore ha dei valori. Il mio comando SQL è di selezionare solo 1 colonna da una tabella. La colonna contiene SOLO stringhe. Voglio leggere le stringhe (righe) nel lettore una per una. Come faccio a fare questo?

Risposte:


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

o

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

Questi sono object, quindi è necessario lanciarli o .ToString().


3
l'operatore [] restituisce un oggetto, dovrai lanciarlo come una stringa.
Scott Chamberlain,

Se si utilizzano indici come reader.GetString (0), utilizzerà la prima colonna selezionata nella query o la prima colonna nella tabella. Ho una tabella con 3 colonne in ordine: ID, Dir, Email. Il mio comando seleziona dir ed e-mail. Reader.GetStrting (0) recupererà dir o ID? Gli indici sono basati sulla tabella stessa su SQL Server o sulla query eseguita per selezionare colonne da una tabella?
Shenk,

1
@shenk Gli indici si basano sull'ordine dei parametri selezionati. Ad ogni modo, è meglio usare i nomi delle colonne o gli alias (cioè rdr ["ID"] invece di rdr [0])
Mark Avenius,

1
@MarkAvenius era che l'indicizzazione tramite ordinali numerici ha ottenuto un miglioramento delle prestazioni rispetto ai nomi di colonna / alias - non sono sicuro che sia ancora così
BaltoStar

3
@BaltoStar che è interessante; Non ne ero a conoscenza. Tuttavia, a seconda della differenza di prestazioni (soprattutto rispetto alla trasmissione di dati via cavo, in base alla tua applicazione) direi generalmente che la leggibilità e la manutenibilità di vedere i nomi delle colonne trionferanno qualsiasi miglioramento marginale delle prestazioni. Grazie!
Mark Avenius,

36

Inserisci il nome della colonna inizio restituito dal database dove si "ColumnName"trova. Se è una stringa, puoi usare .ToString(). Se si tratta di un altro tipo, è necessario convertirlo utilizzando 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();
}

funzionerà


3
toString()non è valido dovrebbe essere .ToString()solo fyi
MethodMan

1
@MethodMan grazie per le tue informazioni. Ho modificato la mia risposta secondo il tuo suggerimento.
Mohini Mhetre,

Ciao, come posso ottenere la riga come oggetti e non per colonna? Ad esempio {id: 1, name: 'John'}
Binsoi,

e se volessi qualcosa di simile qui sotto. if (rdr [0]) {// fai qualcosa qui} altrimenti if (rdr [1]) {// fai qualcosa qui} Ho provato a lanciarlo bool ma dà un errore di cast invalido
Fahad Ejaz Butt

16

Per un singolo risultato:

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

Per più risultati:

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

15

Ho pensato di condividere il mio metodo di supporto per coloro che possono usarlo:

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

Uso:

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

Il metodo helper esegue il cast su qualsiasi valore ti piaccia, se non può eseguire il cast o il valore del database è NULL, il risultato sarà null.


2
Bel pezzo di codice, l'ho modificato per essere un metodo di estensione e funziona molto benereader.GetColumn<int>("M_ID");
Ali Umair

8

In realtà, ho capito da solo che avrei potuto farlo:

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

1
Non vedo come questo approccio sia più complicato degli altri. Trim()non è stato menzionato nella domanda e così è qui ma non nelle altre risposte.
jwg

7

So che questo è un po 'vecchio ma se stai leggendo il contenuto di un SqlDataReader in una classe, questo sarà molto utile. i nomi delle colonne di reader e class dovrebbero essere uguali

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

Questa dovrebbe essere una risposta raccomandata. Modo molto generico per restituire un elenco digitato.
kotpal,

7

Direi contro usando SqlDataReaderqui; ADO.NET ha molti casi limite e complicazioni, e nella mia esperienza il codice ADO.NET scritto più manualmente è rotto in almeno un modo (di solito sottile e contestuale).

Esistono strumenti per evitarlo. Ad esempio, nel caso qui desideri leggere una colonna di stringhe. Dapper lo rende completamente indolore:

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

Dapper qui ha a che fare con tutta la parametrizzazione, l'esecuzione e l'elaborazione delle righe - e molti altri dettagli sgangherati di ADO.NET. La <string>può essere sostituito con <SomeType>materializzare intere righe in oggetti.


6

In parole povere, se la query restituisce nome_colonna e contiene una stringa:

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

1
Al momento i metodi .getXXX sul lettore accettano solo un numero intero ordinale.
Cos Callis,

3

Ho una funzione di supporto come:

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

        return o.ToString();
    }

quindi lo uso per estrarre la stringa:

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

1
Convert.ToString standard (o) fa lo stesso, poiché DBNull è IConvertible e DBNull.ToString () restituisce string.Empty.
nzeemin,

Hai ragione, ma non sono sicuro che l'abbia fatto quando l'ho pubblicato.
JBrooks,

3

Di solito leggo i dati dal lettore di dati in questo modo. ho appena aggiunto un piccolo esempio.

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

Devi read database columnqui. Puoi dare un'occhiata al seguente frammento di codice

                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();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.