Recupero di dati tramite un oggetto DataReaderRetrieving Data Using a DataReader

Recupero di dati mediante un DataReader comporta la creazione di un'istanza del comando oggetto e quindi creando un DataReader chiamando Command. ExecuteReader per recuperare righe da un'origine dati.Retrieving data using a DataReader involves creating an instance of the Command object and then creating a DataReader by calling Command.ExecuteReader to retrieve rows from a data source. Nell'esempio seguente viene illustrato l'utilizzo un DataReader in reader rappresenta un DataReader valido e command rappresenta un oggetto Command valido.The following example illustrates using a DataReader where reader represents a valid DataReader and command represents a valid Command object.

reader = command.ExecuteReader();  

Utilizzare il lettura metodo il DataReader per ottenere una riga dai risultati della query.You use the Read method of the DataReader object to obtain a row from the results of the query. È possibile accedere a ogni colonna della riga restituita passando il nome o il riferimento ordinale della colonna di DataReader.You can access each column of the returned row by passing the name or ordinal reference of the column to the DataReader. Tuttavia, per prestazioni ottimali, il DataReader fornisce una serie di metodi che consentono di accedere ai valori di colonna nei tipi di dati nativi (GetDateTime, GetDouble, GetGuid, GetInt32e così via).However, for best performance, the DataReader provides a series of methods that allow you to access column values in their native data types (GetDateTime, GetDouble, GetGuid, GetInt32, and so on). Per un elenco di metodi di funzioni di accesso tipizzate per dati specifici del provider DataReader, vedere OleDbDataReader e SqlDataReader.For a list of typed accessor methods for data provider-specific DataReaders, see OleDbDataReader and SqlDataReader. L'utilizzo di metodi di funzioni di accesso tipizzate, quando si conosce il tipo di dati sottostante, riduce il numero di conversioni dei tipi necessari al momento del recupero del valore della colonna.Using the typed accessor methods, assuming the underlying data type is known, reduces the amount of type conversion required when retrieving the column value.

Nota

La versione di Windows Server 2003 di .NET Framework include una proprietà aggiuntiva per il DataReader, HasRows, che consente di determinare se il DataReaderha restituito risultati prima di leggere da esso.The Windows Server 2003 release of the .NET Framework includes an additional property for the DataReader, HasRows, which enables you to determine if the DataReader has returned any results before reading from it.

Esempio di codice seguente si scorre un DataReader oggetto e restituisce due colonne di ogni riga.The following code example iterates through a DataReader object, and returns two columns from each row.

static void HasRows(SqlConnection connection)
{
    using (connection)
    {
        SqlCommand command = new SqlCommand(
          "SELECT CategoryID, CategoryName FROM Categories;",
          connection);
        connection.Open();

        SqlDataReader reader = command.ExecuteReader();

        if (reader.HasRows)
        {
            while (reader.Read())
            {
                Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
                    reader.GetString(1));
            }
        }
        else
        {
            Console.WriteLine("No rows found.");
        }
        reader.Close();
    }
}
Private Sub HasRows(ByVal connection As SqlConnection)
    Using connection
        Dim command As SqlCommand = New SqlCommand( _
          "SELECT CategoryID, CategoryName FROM Categories;", _
          connection)
        connection.Open()

        Dim reader As SqlDataReader = command.ExecuteReader()

        If reader.HasRows Then
            Do While reader.Read()
                Console.WriteLine(reader.GetInt32(0) _
                  & vbTab & reader.GetString(1))
            Loop
        Else
            Console.WriteLine("No rows found.")
        End If

        reader.Close()
    End Using
End Sub

Il DataReader fornisce un flusso non memorizzato nel buffer di dati che consente una logica procedurale di elaborare sequenzialmente i risultati da un'origine dati in modo sequenziale.The DataReader provides an unbuffered stream of data that allows procedural logic to efficiently process results from a data source sequentially. Il DataReader è una scelta ottimale quando si recuperano grandi quantità di dati perché i dati non è stato memorizzato nella cache in memoria.The DataReader is a good choice when retrieving large amounts of data because the data is not cached in memory.

Chiusura dell'oggetto DataReaderClosing the DataReader

È necessario chiamare sempre il Chiudi metodo al termine dell'utilizzo di DataReader oggetto.You should always call the Close method when you have finished using the DataReader object.

Se il comando output contiene parametri o valori restituiti, non saranno disponibili finché il DataReader viene chiuso.If your Command contains output parameters or return values, they will not be available until the DataReader is closed.

Si noti che, sebbene un DataReader è aperto, il connessione viene utilizzato esclusivamente da che DataReader.Note that while a DataReader is open, the Connection is in use exclusively by that DataReader. Non è possibile eseguire i comandi per il connessione, inclusa la creazione di un altro DataReader, fino a quando originale DataReader viene chiuso.You cannot execute any commands for the Connection, including creating another DataReader, until the original DataReader is closed.

Nota

Non chiamare Chiudi o Dispose su un connessione, DataReader, o qualsiasi altro oggetto gestito nel Finalize metodo della classe.Do not call Close or Dispose on a Connection, a DataReader, or any other managed object in the Finalize method of your class. Nei finalizzatori rilasciare solo le risorse non gestite che la classe controlla direttamente.In a finalizer, only release unmanaged resources that your class owns directly. Se la classe non dispone di risorse non gestite, non includere un Finalize metodo nella definizione della classe.If your class does not own any unmanaged resources, do not include a Finalize method in your class definition. Per ulteriori informazioni, vedere Garbage Collection.For more information, see Garbage Collection.

Recupero di più set di risultati tramite NextResultRetrieving Multiple Result Sets using NextResult

Se vengono restituiti più set di risultati, il DataReader fornisce il NextResult Imposta metodo per scorrere il risultato in ordine.If multiple result sets are returned, the DataReader provides the NextResult method to iterate through the result sets in order. Nell'esempio seguente viene illustrata l'elaborazione dei risultati di due dichiarazioni SELECT da parte del tipo SqlDataReader usando il metodo ExecuteReader.The following example shows the SqlDataReader processing the results of two SELECT statements using the ExecuteReader method.

static void RetrieveMultipleResults(SqlConnection connection)
{
    using (connection)
    {
        SqlCommand command = new SqlCommand(
          "SELECT CategoryID, CategoryName FROM dbo.Categories;" +
          "SELECT EmployeeID, LastName FROM dbo.Employees",
          connection);
        connection.Open();

        SqlDataReader reader = command.ExecuteReader();

        while (reader.HasRows)
        {
            Console.WriteLine("\t{0}\t{1}", reader.GetName(0),
                reader.GetName(1));

            while (reader.Read())
            {
                Console.WriteLine("\t{0}\t{1}", reader.GetInt32(0),
                    reader.GetString(1));
            }
            reader.NextResult();
        }
    }
}
Private Sub RetrieveMultipleResults(ByVal connection As SqlConnection)
    Using connection
        Dim command As SqlCommand = New SqlCommand( _
          "SELECT CategoryID, CategoryName FROM Categories;" & _
          "SELECT EmployeeID, LastName FROM Employees", connection)
        connection.Open()

        Dim reader As SqlDataReader = command.ExecuteReader()

        Do While reader.HasRows
            Console.WriteLine(vbTab & reader.GetName(0) _
              & vbTab & reader.GetName(1))

            Do While reader.Read()
                Console.WriteLine(vbTab & reader.GetInt32(0) _
                  & vbTab & reader.GetString(1))
            Loop

            reader.NextResult()
        Loop
    End Using
End Sub

Recupero di informazioni sullo schema dall'oggetto DataReaderGetting Schema Information from the DataReader

Mentre un DataReader è aperto, è possibile recuperare informazioni sullo schema relative corrente insieme di risultati utilizzando il GetSchemaTable metodo.While a DataReader is open, you can retrieve schema information about the current result set using the GetSchemaTable method. GetSchemaTable restituisce un DataTable oggetto compilato con righe e colonne che contengono le informazioni sullo schema per il set di risultati corrente.GetSchemaTable returns a DataTable object populated with rows and columns that contain the schema information for the current result set. Il DataTable contiene una riga per ogni colonna del set di risultati.The DataTable contains one row for each column of the result set. Esegue il mapping di ogni colonna della riga della tabella dello schema a una proprietà della colonna restituita nel set di risultati, in cui il ColumnName è il nome della proprietà e il valore della colonna è il valore della proprietà.Each column of the schema table row maps to a property of the column returned in the result set, where the ColumnName is the name of the property and the value of the column is the value of the property. Esempio di codice seguente scrive le informazioni sullo schema per DataReader.The following code example writes out the schema information for DataReader.

static void GetSchemaInfo(SqlConnection connection)
{
    using (connection)
    {
        SqlCommand command = new SqlCommand(
          "SELECT CategoryID, CategoryName FROM Categories;",
          connection);
        connection.Open();

        SqlDataReader reader = command.ExecuteReader();
        DataTable schemaTable = reader.GetSchemaTable();

        foreach (DataRow row in schemaTable.Rows)
        {
            foreach (DataColumn column in schemaTable.Columns)
            {
                Console.WriteLine(String.Format("{0} = {1}",
                   column.ColumnName, row[column]));
            }
        }
    }
}
Private Sub GetSchemaInfo(ByVal connection As SqlConnection)
    Using connection
        Dim command As SqlCommand = New SqlCommand( _
          "SELECT CategoryID, CategoryName FROM Categories;", _
          connection)
        connection.Open()

        Dim reader As SqlDataReader = command.ExecuteReader()
        Dim schemaTable As DataTable = reader.GetSchemaTable()

        Dim row As DataRow
        Dim column As DataColumn

        For Each row In schemaTable.Rows
            For Each column In schemaTable.Columns
                Console.WriteLine(String.Format("{0} = {1}", _
                  column.ColumnName, row(column)))
            Next
            Console.WriteLine()
        Next
        reader.Close()
    End Using
End Sub

Utilizzo dei capitoli OLE DBWorking with OLE DB Chapters

Set di righe gerarchici, o capitoli (tipo OLE DB DBTYPE_HCHAPTER, tipo ADO adChapter) può essere recuperato tramite il OleDbDataReader.Hierarchical rowsets, or chapters (OLE DB type DBTYPE_HCHAPTER, ADO type adChapter) can be retrieved using the OleDbDataReader. Quando una query che include un capitolo viene restituita come un DataReader, il capitolo viene restituito come una colonna in cui DataReader ed è esposto come un DataReader oggetto.When a query that includes a chapter is returned as a DataReader, the chapter is returned as a column in that DataReader and is exposed as a DataReader object.

ADO.NET DataSet può anche essere utilizzato per rappresentare rowset gerarchici usando relazioni padre-figlio tra le tabelle.The ADO.NET DataSet can also be used to represent hierarchical rowsets using parent-child relationships between tables. Per ulteriori informazioni, vedere DataSet, DataTable e DataView.For more information, see DataSets, DataTables, and DataViews.

Nell'esempio di codice seguente viene usato il provider MSDataShape per generare una colonna del capitolo contenente gli ordini per ogni cliente presente in un elenco di clienti.The following code example uses the MSDataShape Provider to generate a chapter column of orders for each customer in a list of customers.

Using connection As OleDbConnection = New OleDbConnection( _  
  "Provider=MSDataShape;Data Provider=SQLOLEDB;" & _  
  "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind")  

Dim custCMD As OleDbCommand = New OleDbCommand( _  
  "SHAPE {SELECT CustomerID, CompanyName FROM Customers} " & _  
  "APPEND ({SELECT CustomerID, OrderID FROM Orders} AS CustomerOrders " & _  
  "RELATE CustomerID TO CustomerID)", connection)  
connection.Open()  

Dim custReader As OleDbDataReader = custCMD.ExecuteReader()  
Dim orderReader As OleDbDataReader  

Do While custReader.Read()  
  Console.WriteLine("Orders for " & custReader.GetString(1))   
  ' custReader.GetString(1) = CompanyName  

  orderReader = custReader.GetValue(2)  
  ' custReader.GetValue(2) = Orders chapter as DataReader  

  Do While orderReader.Read()  
    Console.WriteLine(vbTab & orderReader.GetInt32(1))  
    ' orderReader.GetInt32(1) = OrderID  
  Loop  
  orderReader.Close()  
Loop  
' Make sure to always close readers and connections.  
custReader.Close()  
End Using  
Using (OleDbConnection connection = new OleDbConnection(  
  "Provider=MSDataShape;Data Provider=SQLOLEDB;" +  
  "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind"));  
{  
OleDbCommand custCMD = new OleDbCommand(  
  "SHAPE {SELECT CustomerID, CompanyName FROM Customers} " +  
  "APPEND ({SELECT CustomerID, OrderID FROM Orders} AS CustomerOrders " +  
  "RELATE CustomerID TO CustomerID)", connection);  
connection.Open();  

OleDbDataReader custReader = custCMD.ExecuteReader();  
OleDbDataReader orderReader;  

while (custReader.Read())  
{  
  Console.WriteLine("Orders for " + custReader.GetString(1));   
  // custReader.GetString(1) = CompanyName  

  orderReader = (OleDbDataReader)custReader.GetValue(2);        
  // custReader.GetValue(2) = Orders chapter as DataReader  

  while (orderReader.Read())  
    Console.WriteLine("\t" + orderReader.GetInt32(1));          
    // orderReader.GetInt32(1) = OrderID  
  orderReader.Close();  
}  
// Make sure to always close readers and connections.  
custReader.Close();  
}  

Restituzione di risultati con i REF CURSOR OracleReturning Results with Oracle REF CURSORs

Con il provider di dati .NET Framework per Oracle è possibile usare i REF CURSOR Oracle per la restituzione del risultato di una query.The .NET Framework Data Provider for Oracle supports the use of Oracle REF CURSORs to return a query result. I REF CURSOR Oracle vengono restituiti come OracleDataReader.An Oracle REF CURSOR is returned as an OracleDataReader.

È possibile recuperare un OracleDataReader oggetto, che rappresenta un REF CURSOR Oracle usando il ExecuteReader metodo ed è inoltre possibile specificare un OracleCommand che restituisce uno o più REF CURSOR Oracle come il SelectCommand per un OracleDataAdapter usato per riempire un DataSet.You can retrieve an OracleDataReader object, that represents an Oracle REF CURSOR using the ExecuteReader method, and you can also specify an OracleCommand that returns one or more Oracle REF CURSORs as the SelectCommand for an OracleDataAdapter used to fill a DataSet.

Per accedere a un REF CURSOR restituito da un'origine dati Oracle, creare un OracleCommand per la query e aggiungere un parametro di output che fa riferimento al REF CURSOR al parametri insieme il OracleCommand.To access a REF CURSOR returned from an Oracle data source, create an OracleCommand for your query and add an output parameter that references the REF CURSOR to the Parameters collection of your OracleCommand. È necessario che il nome del parametro corrisponda al nome del parametro REF CURSOR della query.The name of the parameter must match the name of the REF CURSOR parameter in your query. Impostare il tipo del parametro da OracleType. Cursor.Set the type of the parameter to OracleType.Cursor. Il ExecuteReader metodo i OracleCommand restituirà un OracleDataReader per il REF CURSOR.The ExecuteReader method of your OracleCommand will return an OracleDataReader for the REF CURSOR.

Se il OracleCommand restituisce più REF CURSOR, aggiungere più parametri di output.If your OracleCommand returns multiple REF CURSORS, add multiple output parameters. È possibile accedere ai diversi REF CURSOR chiamando il OracleCommand metodo.You can access the different REF CURSORs by calling the OracleCommand.ExecuteReader method. La chiamata a ExecuteReader restituisce un OracleDataReader che fa riferimento al primo REF CURSOR.The call to ExecuteReader returns an OracleDataReader referencing the first REF CURSOR. È quindi possibile chiamare il OracleDataReader. NextResult per accedere a REF CURSOR successivi.You can then call the OracleDataReader.NextResult method to access subsequent REF CURSORs. Anche se i parametri del OracleCommand corrispondenza insieme al REF CURSOR i parametri di output in base al nome, il OracleDataReader accederà ai parametri nell'ordine in cui sono stati aggiunti per il I parametri insieme.Although the parameters in your OracleCommand.Parameters collection match the REF CURSOR output parameters by name, the OracleDataReader accesses them in the order that they were added to the Parameters collection.

Si considerino ad esempio il package e il corpo package Oracle seguenti.For example, consider the following Oracle package and package body.

CREATE OR REPLACE PACKAGE CURSPKG AS   
  TYPE T_CURSOR IS REF CURSOR;   
  PROCEDURE OPEN_TWO_CURSORS (EMPCURSOR OUT T_CURSOR,   
    DEPTCURSOR OUT T_CURSOR);   
END CURSPKG;  

CREATE OR REPLACE PACKAGE BODY CURSPKG AS   
  PROCEDURE OPEN_TWO_CURSORS (EMPCURSOR OUT T_CURSOR,   
    DEPTCURSOR OUT T_CURSOR)   
  IS   
  BEGIN   
    OPEN EMPCURSOR FOR SELECT * FROM DEMO.EMPLOYEE;   
    OPEN DEPTCURSOR FOR SELECT * FROM DEMO.DEPARTMENT;   
  END OPEN_TWO_CURSORS;   
END CURSPKG;   

Il codice seguente crea un OracleCommand che restituisce i REF CURSOR dal package Oracle precedente tramite l'aggiunta di due parametri di tipo OracleType. Cursor per il parametri insieme.The following code creates an OracleCommand that returns the REF CURSORs from the previous Oracle package by adding two parameters of type OracleType.Cursor to the Parameters collection.

Dim cursCmd As OracleCommand = New OracleCommand("CURSPKG.OPEN_TWO_CURSORS", oraConn)  
cursCmd.Parameters.Add("EMPCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output  
cursCmd.Parameters.Add("DEPTCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output  
OracleCommand cursCmd = new OracleCommand("CURSPKG.OPEN_TWO_CURSORS", oraConn);  
cursCmd.Parameters.Add("EMPCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output;  
cursCmd.Parameters.Add("DEPTCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output;  

Il codice seguente restituisce i risultati del comando precedente tramite il lettura e NextResult metodi di OracleDataReader.The following code returns the results of the previous command using the Read and NextResult methods of the OracleDataReader. I parametri REF CURSOR vengono restituiti in ordine.The REF CURSOR parameters are returned in order.

oraConn.Open()  

Dim cursCmd As OracleCommand = New OracleCommand("CURSPKG.OPEN_TWO_CURSORS", oraConn)  
cursCmd.CommandType = CommandType.StoredProcedure  
cursCmd.Parameters.Add("EMPCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output  
cursCmd.Parameters.Add("DEPTCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output  

Dim reader As OracleDataReader = cursCmd.ExecuteReader()  

Console.WriteLine(vbCrLf & "Emp ID" & vbTab & "Name")  

Do While reader.Read()  
  Console.WriteLine("{0}" & vbTab & "{1}, {2}", reader.GetOracleNumber(0), reader.GetString(1), reader.GetString(2))  
Loop  

reader.NextResult()  

Console.WriteLine(vbCrLf & "Dept ID" & vbTab & "Name")  

Do While reader.Read()  
  Console.WriteLine("{0}" & vbTab & "{1}", reader.GetOracleNumber(0), reader.GetString(1))  
Loop  
' Make sure to always close readers and connections.  
reader.Close()  
oraConn.Close()  
oraConn.Open();  

OracleCommand cursCmd = new OracleCommand("CURSPKG.OPEN_TWO_CURSORS", oraConn);  
cursCmd.CommandType = CommandType.StoredProcedure;  
cursCmd.Parameters.Add("EMPCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output;  
cursCmd.Parameters.Add("DEPTCURSOR", OracleType.Cursor).Direction = ParameterDirection.Output;  

OracleDataReader reader = cursCmd.ExecuteReader();  

Console.WriteLine("\nEmp ID\tName");  

while (reader.Read())  
  Console.WriteLine("{0}\t{1}, {2}", reader.GetOracleNumber(0), reader.GetString(1), reader.GetString(2));  

reader.NextResult();  

Console.WriteLine("\nDept ID\tName");  

while (reader.Read())  
  Console.WriteLine("{0}\t{1}", reader.GetOracleNumber(0), reader.GetString(1));  
// Make sure to always close readers and connections.  
reader.Close();  
oraConn.Close();  

Nell'esempio seguente viene utilizzato il comando precedente per popolare un DataSet con i risultati del package Oracle.The following example uses the previous command to populate a DataSet with the results of the Oracle package.

Nota

Per evitare un OverflowException, si consiglia di gestire le conversioni dal tipo NUMBER Oracle in un tipo .NET Framework valido prima di archiviare i valori in un DataRow.To avoid an OverflowException, we recommend that you also handle any conversion from the Oracle NUMBER type to a valid .NET Framework type before storing the value in a DataRow. È possibile utilizzare il FillError evento per determinare se un OverflowException si è verificato.You can use the FillError event to determine if an OverflowException has occurred. Per ulteriori informazioni sul FillError eventi, vedere gestione di eventi DataAdapter.For more information on the FillError event, see Handling DataAdapter Events.

Dim ds As DataSet = New DataSet()  

Dim adapter As OracleDataAdapter = New OracleDataAdapter(cursCmd)  
adapter.TableMappings.Add("Table", "Employees")  
adapter.TableMappings.Add("Table1", "Departments")  

adapter.Fill(ds)  
DataSet ds = new DataSet();  

OracleDataAdapter adapter = new OracleDataAdapter(cursCmd);  
adapter.TableMappings.Add("Table", "Employees");  
adapter.TableMappings.Add("Table1", "Departments");  

adapter.Fill(ds);  

Vedere ancheSee Also

Utilizzo di DataReaderWorking with DataReaders
DataAdapter e DataReaderDataAdapters and DataReaders
Comandi e parametriCommands and Parameters
Recupero di informazioni sullo schema del databaseRetrieving Database Schema Information
Provider gestiti ADO.NET e Centro per sviluppatori di set di datiADO.NET Managed Providers and DataSet Developer Center