Abrufen von Daten, die mit "DataReader"Retrieve data using a DataReader

Zum Abrufen von Daten mithilfe einer DataReader, erstellen Sie eine Instanz von der Befehl Objekt aus, und erstellen Sie eine DataReader durch Aufrufen von Command.ExecuteReader um Zeilen aus einer Datenquelle abzurufen.To retrieve data using a DataReader, create an instance of the Command object, and then create a DataReader by calling Command.ExecuteReader to retrieve rows from a data source. Die DataReader enthält einen nicht gepufferten Datenstream, mit der prozeduralen Logik, die Ergebnisse aus einer Datenquelle effizient sequenziell zu verarbeiten zu können.The DataReader provides an unbuffered stream of data that allows procedural logic to efficiently process results from a data source sequentially. Die DataReader ist eine gute Wahl, wenn Sie große Mengen von Daten abgerufen werden, da die Daten nicht im Arbeitsspeicher zwischengespeichert werden.The DataReader is a good choice when you're retrieving large amounts of data because the data is not cached in memory.

Das folgende Beispiel veranschaulicht die Verwendung einer DataReader, wobei reader stellt ein gültiger DataReader-Ziel und command ein gültiges Command-Objekt darstellt.The following example illustrates using a DataReader, where reader represents a valid DataReader and command represents a valid Command object.

reader = command.ExecuteReader();  
reader = command.ExecuteReader()

Verwenden der DataReader.Read Methode, um eine Zeile aus die Ergebnisse der Abfrage abzurufen.Use the DataReader.Read method to obtain a row from the query results. Sie können jede Spalte der zurückgegebenen Zeile zugreifen, indem Sie übergeben den Namen oder die Ordnungszahl der Spalte, die die DataReader.You can access each column of the returned row by passing the name or ordinal number of the column to the DataReader. Allerdings für eine optimale Leistung die DataReader enthält eine Reihe von Methoden, die Sie auf Spaltenwerte in deren systemeigenen Datentypen zugreifen können (GetDateTime, GetDouble, GetGuid, GetInt32und so weiter).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). Eine Liste der typisierten Zugriffsmethoden für anbieterspezifische "DataReaders", finden Sie unter OleDbDataReader und SqlDataReader.For a list of typed accessor methods for data provider-specific DataReaders, see OleDbDataReader and SqlDataReader. Verwenden die typisierten Accessormethoden bereit, wenn Sie wissen, dass die zugrunde liegenden Daten verringert Typ die Typumwandlung erforderlich, wenn der Wert der Spalte abrufen.Using the typed accessor methods when you know the underlying data type reduces the amount of type conversion required when retrieving the column value.

Das folgende Beispiel durchläuft einen DataReader -Objekt und zwei Spalten aus jeder Zeile zurückgegeben.The following 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

Schließen des "DataReader"Closing the DataReader

Rufen Sie immer die schließen Methode, wenn Sie aufgehört haben die DataReader Objekt.Always call the Close method when you have finished using the DataReader object.

Wenn Ihre Befehl enthält die Ausgabe Parameter oder Rückgabewerte, sind diese Werte nicht verfügbar, bis die DataReader geschlossen wird.If your Command contains output parameters or return values, those values are not available until the DataReader is closed.

Während einer DataReader geöffnet ist, die Verbindung wird ausschließlich von diesem DataReader.While a DataReader is open, the Connection is in use exclusively by that DataReader. Sie können nicht ausgeführt werden Befehle für die Verbindung, einschließlich der Erstellung eines weiteren DataReader, bis die ursprüngliche DataReader geschlossen wird.You cannot execute any commands for the Connection, including creating another DataReader, until the original DataReader is closed.

Hinweis

Rufen Sie nicht schließen oder Dispose auf eine Verbindung, DataReader, oder andere verwaltete Objekte in der abschließen Methode der Klasse.Do not call Close or Dispose on a Connection, a DataReader, or any other managed object in the Finalize method of your class. Geben Sie in einer Finalize-Methode nur nicht verwaltete Ressourcen frei, die der Klasse direkt gehören.In a finalizer, only release unmanaged resources that your class owns directly. Wenn Ihre Klasse keine nicht verwalteten Ressourcen besitzt, ist nicht enthalten. ein Finalize Methode in der Klassendefinition.If your class does not own any unmanaged resources, do not include a Finalize method in your class definition. Weitere Informationen finden Sie unter Garbage Collection.For more information, see Garbage Collection.

Abrufen von mehreren Resultsets legt fest, die mit "NextResult"Retrieving multiple result sets using NextResult

Wenn die DataReader mehrere Resultsets Aufruf gibt die NextResult Methode zum iterieren durch das Ergebnis wird sequenziell.If the DataReader returns multiple result sets, call the NextResult method to iterate through the result sets sequentially. Im folgenden Beispiel werden die Ergebnisse von zwei SELECT-Anweisungen mit der SqlDataReader-Methode von ExecuteReader verarbeitet.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

Abrufen von Schemainformationen vom DataReaderGetting schema information from the DataReader

Während einer DataReader ist geöffnet ist, können die Schemainformationen über das aktuelle Resultset mit Abrufen der GetSchemaTable Methode.While a DataReader is open, you can retrieve schema information about the current result set using the GetSchemaTable method. GetSchemaTable gibt eine DataTable -Objekt mit den Zeilen und Spalten, die die Schemainformationen für das aktuelle Resultset enthalten.GetSchemaTable returns a DataTable object populated with rows and columns that contain the schema information for the current result set. Die DataTable enthält eine Zeile für jede Spalte des Resultsets.The DataTable contains one row for each column of the result set. Jede Spalte der Schematabelle ordnet eine Eigenschaft, die Spalten, die Zeilen des Resultsets festgelegt, wobei die ColumnName ist der Name der Eigenschaft und der Wert der Spalte den Wert der Eigenschaft.Each column of the schema table maps to a property of the columns returned in the rows of the result set, where the ColumnName is the name of the property and the value of the column is the value of the property. Im folgende Beispiel schreibt die Schemainformationen für DataReader.The following 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

Arbeiten mit OLE DB-KapitelWorking with OLE DB chapters

Hierarchische Rowsets oder Kapitel (OLE DB-Typ DBTYPE_HCHAPTER, ADO-Typ AdChapter), können abgerufen werden, mithilfe der OleDbDataReader.Hierarchical rowsets, or chapters (OLE DB type DBTYPE_HCHAPTER, ADO type adChapter), can be retrieved using the OleDbDataReader. Wenn eine Abfrage, die einem Kapitel zurückgegeben wird, als eine DataReader, das Kapitel als Spalte in diesem zurückgegeben wird DataReader und als verfügbar gemacht wird eine DataReader Objekt.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 kann auch verwendet werden, um hierarchische Rowsets mit über-und untergeordnete Beziehungen zwischen Tabellen darstellen.The ADO.NET DataSet can also be used to represent hierarchical rowsets by using parent-child relationships between tables. Weitere Informationen finden Sie unter DataSets, DataTables und DataViews.For more information, see DataSets, DataTables, and DataViews.

Im folgenden Codebeispiel wird mit dem MSDataShape-Anbieter eine Kapitelspalte mit Bestellungen für jeden Kunden in einer Kundenliste generiert.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")

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

        Using custReader As OleDbDataReader = custCMD.ExecuteReader()

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

                Using orderReader As OleDbDataReader = 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()
                End Using
            Loop
            ' Make sure to always close readers and connections.  
            custReader.Close()
        End Using
    End Using
End Using
using (OleDbConnection connection = new OleDbConnection(
    "Provider=MSDataShape;Data Provider=SQLOLEDB;" +
    "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind"))
{
    using (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();

        using (OleDbDataReader custReader = custCMD.ExecuteReader())
        {

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

                using (OleDbDataReader 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();
        }
    }
}

Zurückgeben von Ergebnissen mit Oracle-REF CURSORsReturning results with Oracle REF CURSORs

Der .NET Framework-Datenanbieter für Oracle unterstützt die Verwendung von Oracle-REF CURSORs zur Rückgabe eines Abfrageergebnisses.The .NET Framework Data Provider for Oracle supports the use of Oracle REF CURSORs to return a query result. Ein Oracle-REF CURSOR wird als OracleDataReader zurückgegeben.An Oracle REF CURSOR is returned as an OracleDataReader.

Können Sie Abrufen einer OracleDataReader Objekt, eine Oracle-REF CURSOR darstellt, mit, der ExecuteReader Methode.You can retrieve an OracleDataReader object that represents an Oracle REF CURSOR by using the ExecuteReader method. Sie können auch angeben einer OracleCommand , die eine oder mehrere Oracle-REF CURSORs als zurückgibt der SelectCommand für eine OracleDataAdapter verwendet, um eine DataSet.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.

Erstellen Sie aus einer Oracle-Datenquelle zurückgegebenen REF CURSOR für den Zugriff auf eine OracleCommand für die Abfrage und fügen Sie einen Output-Parameter, die den REF CURSOR verweist die Parameters Auflistung von Ihrer 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. Der Name des Parameters muss mit dem Namen des REF CURSOR-Parameters in der Abfrage übereinstimmen.The name of the parameter must match the name of the REF CURSOR parameter in your query. Legen Sie den Typ des Parameters, der OracleType.Cursor.Set the type of the parameter to OracleType.Cursor. Die OracleCommand.ExecuteReader() Methode Ihrer OracleCommand gibt ein OracleDataReader für den REF CURSOR.The OracleCommand.ExecuteReader() method of your OracleCommand returns an OracleDataReader for the REF CURSOR.

Wenn Ihre OracleCommand mehrere REF CURSORS zurückgibt fügen Sie mehrere Ausgabeparameter hinzu.If your OracleCommand returns multiple REF CURSORS, add multiple output parameters. Sie können die verschiedenen REF CURSORs zugreifen, durch den Aufruf der OracleCommand.ExecuteReader() Methode.You can access the different REF CURSORs by calling the OracleCommand.ExecuteReader() method. Der Aufruf von ExecuteReader() gibt ein OracleDataReader auf den ersten REF CURSOR verweist.The call to ExecuteReader() returns an OracleDataReader referencing the first REF CURSOR. Rufen Sie anschließend die OracleDataReader.NextResult() Methode, um die nachfolgenden REF CURSORs zugreifen.You can then call the OracleDataReader.NextResult() method to access subsequent REF CURSORs. Obwohl die Parameter in Ihre OracleCommand.Parameters Auflistung Übereinstimmung den REF CURSOR-Ausgabeparameter anhand des Namens, der OracleDataReader greift auf sie in der Reihenfolge, in dem sie hinzugefügt wurden, die Parameters Auflistung.Although the parameters in your OracleCommand.Parameters collection match the REF CURSOR output parameters by name, the OracleDataReader accesses them in the order in which they were added to the Parameters collection.

Betrachten Sie z. B. das folgende Oracle-Paket und den Paketkörper.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;   

Der folgende Code erstellt ein OracleCommand , aus dem vorherigen Oracle-Paket die REF CURSORs zurückgibt, durch das Hinzufügen von zwei Parametern vom Typ OracleType.Cursor auf die OracleCommand.Parameters Auflistung.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 OracleCommand.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;  

Der folgende Code gibt die Ergebnisse des vorherigen Befehls mit der Read() und NextResult() Methoden der OracleDataReader.The following code returns the results of the previous command using the Read() and NextResult() methods of the OracleDataReader. Die REF CURSOR-Parameter werden der Reihe nach zurückgegeben.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();  

Im folgenden Beispiel wird den vorherigen Befehl zum Auffüllen einer DataSet mit den Ergebnissen des Oracle-Pakets.The following example uses the previous command to populate a DataSet with the results of the Oracle package.

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

Hinweis

Vermeiden einer OverflowException, es wird empfohlen, dass Sie auch jede Konvertierung von Oracle-Typ NUMBER in einen gültigen .NET Framework-Typ vor dem Speichern des Werts in behandeln eine 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. Sie können die FillError Ereignis, um zu bestimmen, ob ein OverflowException aufgetreten.You can use the FillError event to determine if an OverflowException has occurred. Weitere Informationen zu den FillError Ereignis finden Sie unter Behandeln von DataAdapter-Ereignissen.For more information on the FillError event, see Handling DataAdapter Events.

Siehe auchSee also