DataReader を使用してデータを取得するRetrieve data using a DataReader

Datareaderを使用してデータを取得するには、 commandオブジェクトのインスタンスを作成した後、 ExecuteReaderを呼び出してデータソースから行を取得し、 datareaderを作成します。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. DataReaderは、バッファリングされていないデータストリームを提供します。これにより、手続き型のロジックによって、データソースからの結果を順番に効率的に処理できます。The DataReader provides an unbuffered stream of data that allows procedural logic to efficiently process results from a data source sequentially. データがメモリにキャッシュされないため、大量のデータを取得する場合は、 DataReaderを使用することをお勧めします。The DataReader is a good choice when you're retrieving large amounts of data because the data is not cached in memory.

command Datareaderreaderを使用する例を次に示します。は有効な datareader を表し、は有効な Command オブジェクトを表します。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()

クエリ結果から行を取得するには、 DataReader. Readメソッドを使用します。Use the DataReader.Read method to obtain a row from the query results. 返された行の各列には、列の名前または序数をDataReaderに渡すことによってアクセスできます。You can access each column of the returned row by passing the name or ordinal number of the column to the DataReader. ただし、最適なパフォーマンスを得るために、 DataReaderには、ネイティブデータ型 (getdatetimegetdatetimegetdatetimeGetInt32など) の列値にアクセスできる一連のメソッドが用意されています。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). データプロバイダー固有のdatareaderの型指定されたアクセサーメソッドの一覧OleDbDataReaderについては、「」およびSqlDataReader「」を参照してください。For a list of typed accessor methods for data provider-specific DataReaders, see OleDbDataReader and SqlDataReader. 基になるデータ型がわかっている場合は、型指定されたアクセサーメソッドを使用して、列の値を取得するときに必要な型変換の量を減らします。Using the typed accessor methods when you know the underlying data type reduces the amount of type conversion required when retrieving the column value.

次の例では、 DataReaderオブジェクトを反復処理し、各行から2つの列を返します。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

DataReader の終了Closing the DataReader

DataReaderオブジェクトの使用が終了したら、常にCloseメソッドを呼び出します。Always call the Close method when you have finished using the DataReader object.

コマンドに出力パラメーターまたは戻り値が含まれている場合、これらの値はDataReaderが閉じられるまで使用できません。If your Command contains output parameters or return values, those values are not available until the DataReader is closed.

Datareaderが開いている間は、そのdatareaderによって接続が排他的に使用されています。While a DataReader is open, the Connection is in use exclusively by that DataReader. 元のdatareaderが閉じられるまで、接続のコマンド (別のdatareaderの作成を含む) を実行することはできません。You cannot execute any commands for the Connection, including creating another DataReader, until the original DataReader is closed.

注意

クラスのFinalizeメソッドで、接続DataReader、またはその他のマネージオブジェクトに対してCloseまたはDisposeを呼び出さないでください。Do not call Close or Dispose on a Connection, a DataReader, or any other managed object in the Finalize method of your class. 終了処理では、クラスに直接所有されているアンマネージ リソースだけを解放してください。In a finalizer, only release unmanaged resources that your class owns directly. クラスがアンマネージリソースを所有していない場合は、クラス定義にFinalizeメソッドを含めないでください。If your class does not own any unmanaged resources, do not include a Finalize method in your class definition. 詳細については、「ガベージコレクション」を参照してください。For more information, see Garbage Collection.

NextResult を使用して複数の結果セットを取得するRetrieving multiple result sets using NextResult

DataReaderから複数の結果セットが返された場合は、 nextresultメソッドを呼び出して、結果セットを順番に反復処理します。If the DataReader returns multiple result sets, call the NextResult method to iterate through the result sets sequentially. SqlDataReader メソッドを使用して、2 つの SELECT ステートメントの結果を処理する 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

DataReader からのスキーマ情報の取得Getting schema information from the DataReader

DataReaderが開いている間は、 getschematableメソッドを使用して、現在の結果セットに関するスキーマ情報を取得できます。While a DataReader is open, you can retrieve schema information about the current result set using the GetSchemaTable method. Getschematableは、 DataTable現在の結果セットのスキーマ情報を含む行と列を含むオブジェクトを返します。GetSchemaTable returns a DataTable object populated with rows and columns that contain the schema information for the current result set. DataTable には、結果セットの列ごとに1行のデータが格納されます。The DataTable contains one row for each column of the result set. スキーマテーブルの各列は、結果セットの行で返される列のプロパティにマップされます。ここで、 ColumnNameはプロパティの名前、列の値はプロパティの値です。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. 次の例では、 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

OLE DB の章を操作するWorking with OLE DB chapters

階層型の行セット、つまりチャプター (OLE DB type DBTYPE_HCHAPTER、ADO 型adchapter) は、 OleDbDataReaderを使用して取得できます。Hierarchical rowsets, or chapters (OLE DB type DBTYPE_HCHAPTER, ADO type adChapter), can be retrieved using the OleDbDataReader. チャプターを含むクエリがdatareaderとして返された場合、チャプターはそのdatareaderの列として返され、 datareaderオブジェクトとして公開されます。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データセットを使用すると、テーブル間の親子リレーションシップを使用して、階層的な行セットを表すこともできます。The ADO.NET DataSet can also be used to represent hierarchical rowsets by using parent-child relationships between tables. 詳細については、「データセット、datatable、および DataViews」を参照してください。For more information, see DataSets, DataTables, and DataViews.

MSDataShape プロバイダーを使用して、顧客リストの顧客別オーダーのチャプター列を生成するコード サンプルを次に示します。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();
        }
    }
}

Oracle REF cursor を使用して結果を返すReturning results with Oracle REF CURSORs

.NET Framework Data Provider for Oracle は、クエリ結果を返すために、Oracle REF CURSOR の使用をサポートしています。The .NET Framework Data Provider for Oracle supports the use of Oracle REF CURSORs to return a query result. Oracle REF CURSOR は OracleDataReader として返されます。An Oracle REF CURSOR is returned as an OracleDataReader.

Oracle REF カーソルをOracleDataReader表すオブジェクトを取得するには、 ExecuteReaderメソッドを使用します。You can retrieve an OracleDataReader object that represents an Oracle REF CURSOR by using the ExecuteReader method. にデータを格納OracleCommand するためOracleDataAdapterに使用されるのSelectCommandとして1つ以上の Oracle REF cursor を返すを指定することもできます。DataSetYou can also specify an OracleCommand that returns one or more Oracle REF CURSORs as the SelectCommand for an OracleDataAdapter used to fill a DataSet.

Oracle データソースから返された ref カーソルにアクセスするにはOracleCommand 、クエリのを作成し、ref カーソルParametersを参照する出力パラメーターをの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. パラメーターの名前は、クエリの REF CURSOR パラメーターの名前と一致させる必要があります。The name of the parameter must match the name of the REF CURSOR parameter in your query. パラメーターの型をにOracleType.Cursor設定します。Set the type of the parameter to OracleType.Cursor. のメソッドはOracleCommand.ExecuteReader() 、REF カーソルOracleDataReaderのを返します。OracleCommandThe OracleCommand.ExecuteReader() method of your OracleCommand returns an OracleDataReader for the REF CURSOR.

が複数の REF cursorを返す場合は、複数の出力パラメーターを追加します。OracleCommandIf your OracleCommand returns multiple REF CURSORS, add multiple output parameters. 異なる REF カーソルにアクセスするには、 OracleCommand.ExecuteReader()メソッドを呼び出します。You can access the different REF CURSORs by calling the OracleCommand.ExecuteReader() method. の呼び出しExecuteReader()は、最初OracleDataReaderの REF カーソルを参照するを返します。The call to ExecuteReader() returns an OracleDataReader referencing the first REF CURSOR. その後、メソッドをOracleDataReader.NextResult()呼び出して、後続の REF カーソルにアクセスできます。You can then call the OracleDataReader.NextResult() method to access subsequent REF CURSORs. OracleCommand.Parametersコレクション内のパラメーターは、REF CURSOR 出力パラメーターと名前で一致しますOracleDataReaderが、はParametersコレクションに追加された順序でこれらのパラメーターにアクセスします。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.

たとえば、次のような Oracle パッケージとパッケージ本体があるとします。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;   

次のコードは、 OracleCommandOracleType.Cursorの2つのパラメーターをOracleCommand.Parametersコレクションに追加することによって、以前の Oracle パッケージから参照カーソルを返すを作成します。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;  

次のコードは、 Read() OracleDataReaderのメソッドとNextResult()メソッドを使用して、前のコマンドの結果を返します。The following code returns the results of the previous command using the Read() and NextResult() methods of the OracleDataReader. REF CURSOR パラメーターは順番に返されます。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();  

次の例では、前のコマンドをDataSet使用して、Oracle パッケージの結果をに設定します。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);  

注意

OverflowExceptionを回避するには、に値DataRowを格納する前に、Oracle の数値型から有効な .NET Framework 型への変換も処理することをお勧めします。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. イベントを使用しFillErrorて、 OverflowExceptionが発生したかどうかを判断できます。You can use the FillError event to determine if an OverflowException has occurred. FillErrorイベントの詳細については、「 DataAdapter イベントの処理」を参照してください。For more information on the FillError event, see Handling DataAdapter Events.

関連項目See also