Megosztás a következőn keresztül:


Adatok lekérése DataReader használatával

Az adatok DataReaderrel való lekéréséhez hozza létre a Command objektum egy példányát, majd hozzon létre egy DataReadert a Command.ExecuteReader meghívásával, hogy sorokat kérjen le egy adatforrásból. A DataReader egy nem közömbös adatstreamet biztosít, amely lehetővé teszi a procedurális logika számára az adatforrások eredményeinek egymás utáni hatékony feldolgozását. A DataReader jó választás nagy mennyiségű adat lekérésekor, mert az adatok nem gyorsítótárazva vannak a memóriában.

Az alábbi példa egy DataReader használatát szemlélteti, amely reader egy érvényes DataReadert jelöl, és command egy érvényes parancsobjektumot jelöl.

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

A DataReader.Read metódussal beolvashat egy sort a lekérdezés eredményeiből. A visszaadott sor egyes oszlopait úgy érheti el, hogy átadja az oszlop nevét vagy sorszámát a DataReadernek. A legjobb teljesítmény érdekében azonban a DataReader számos olyan metódust biztosít, amelyek lehetővé teszik az oszlopértékek elérését a natív adattípusokban (GetDateTime, GetDouble, GetGuid, GetInt32 stb.). Az adatszolgáltatóspecifikus DataReaders típusozott kiegészítő módszereinek listáját lásd OleDbDataReader és SqlDataReader. Ha ismeri a mögöttes adattípust, a beírt kiegészítő módszerek használata csökkenti az oszlopérték lekéréséhez szükséges típusátalakítás mennyiségét.

Az alábbi példa egy DataReader-objektumon halad végig, és minden sorból két oszlopot ad vissza.

static void HasRows(SqlConnection connection)
{
    using (connection)
    {
        SqlCommand command = new(
          "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

A DataReader bezárása

Mindig hívja meg a Bezárás metódust, ha befejezte a DataReader-objektum használatát.

Ha a parancs kimeneti paramétereket vagy visszaadott értékeket tartalmaz, ezek az értékek csak a DataReader bezárásáig érhetők el.

Amíg a DataReader nyitva van, a Csatlakozás kizárólag az adott DataReader használja. Az Csatlakozás ion parancsai nem hajthatók végre, beleértve egy másik DataReader létrehozását is, amíg az eredeti DataReader be nem záródik.

Feljegyzés

Ne hívja meg a Bezárás vagy a Törlés Csatlakozás ion, DataReader vagy bármely más felügyelt objektum meghívását az osztály Véglegesítés metódusában. A véglegesítőben csak az osztály tulajdonában lévő nem felügyelt erőforrásokat szabadíthatja fel. Ha az osztály nem rendelkezik nem felügyelt erőforrásokkal, ne tartalmazzon Finalize metódust az osztálydefinícióban. További információ: Szemétgyűjtés.

Több eredményhalmaz beolvasása a NextResult használatával

Ha a DataReader több eredményhalmazt ad vissza, hívja meg a NextResult metódust az eredményhalmazok egymás utáni iterálásához. Az alábbi példa két Standard kiadás LECT utasítás eredményeit mutatja SqlDataReader be a ExecuteReader metódus használatával.

static void RetrieveMultipleResults(SqlConnection connection)
{
    using (connection)
    {
        SqlCommand command = new(
          "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

Sémaadatok lekérése a DataReaderből

Amíg a DataReader meg van nyitva, a GetSchemaTable metódussal lekérheti az aktuális eredményhalmaz sémaadatait . A GetSchemaTable egy DataTable olyan sorokkal és oszlopokkal kitöltött objektumot ad vissza, amely az aktuális eredményhalmaz sémaadatait tartalmazza. A DataTable egy sort tartalmaz az eredményhalmaz minden oszlopához. A sématábla minden oszlopa az eredményhalmaz soraiban visszaadott oszlopok egyik tulajdonságához van rendelve, ahol a ColumnName a tulajdonság neve, az oszlop értéke pedig a tulajdonság értéke. Az alábbi példa a DataReader sémaadatait írja le.

static void GetSchemaInfo(SqlConnection connection)
{
    using (connection)
    {
        SqlCommand command = new(
          "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-fejezetek használata

Hierarchikus sorkészletek vagy fejezetek (OLE DB-típus DBTYPE_HCHAPTER, ADO-típus adChapter) a OleDbDataReader. Amikor egy fejezetet tartalmazó lekérdezést ad vissza DataReaderként, a fejezet a DataReader oszlopaként lesz visszaadva, és Adatreader-objektumként lesz közzétéve.

A ADO.NET Adatkészlet a táblák közötti szülő-gyermek kapcsolatok használatával hierarchikus sorhalmazok ábrázolására is használható. További információ: DataSets, DataTables és DataViews.

Az alábbi példakód az MSDataShape-szolgáltatót használja a rendelések fejezetoszlopának létrehozásához az ügyfelek listájában.

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

Eredmények visszaadása Oracle REF CURSOR-okkal

Az Oracle .NET-keretrendszer adatszolgáltatója támogatja az Oracle REF CURSORs használatát a lekérdezés eredményének visszaadásához. Az Oracle REF CURSOR ad vissza OracleDataReader.

A metódussal ExecuteReader lekérhet egy OracleDataReader Oracle REF CURSOR objektumot. Megadhatja azt OracleCommand is, hogy egy vagy több Oracle REF CURSOR-t ad vissza selectCommand értékként egy OracleDataAdapter DataSetkitöltéshez használthoz.

Az Oracle-adatforrásból visszaadott REF CURSOR eléréséhez hozzon létre egy OracleCommand lekérdezést, és adjon hozzá egy kimeneti paramétert, amely a REF CURSOR-ra hivatkozik az Parameters Ön OracleCommandgyűjteményéhez. A paraméter nevének meg kell egyeznie a LEKÉRDEZÉS REF CURSOR paraméterének nevével. Állítsa be a paraméter típusát a következőre OracleType.Cursor: . A OracleCommand.ExecuteReader() metódus OracleCommand a REF CURSOR-hoz ad vissza egy OracleDataReader értéket.

Ha több REF-KURZORT ad OracleCommand vissza, adjon hozzá több kimeneti paramétert. A metódus meghívásával OracleCommand.ExecuteReader() elérheti a különböző REF CURSORs-eket. Az első REF CURSOR-ra hivatkozó hívást ExecuteReader() adja vissza OracleDataReader . Ezután meghívhatja a metódust a OracleDataReader.NextResult() következő REF CURSOR-k eléréséhez. Bár a gyűjtemény paraméterei OracleCommand.Parameters név szerint egyeznek a REF CURSOR kimeneti paraméterekkel, a OracleDataReader rendszer a gyűjteményhez való hozzáadásuk sorrendjében éri el őket Parameters .

Vegyük például az alábbi Oracle-csomagot és csomagtörzset.

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;

Az alábbi kód létrehoz egy OracleCommand olyan kódot, amely az előző Oracle-csomag REF CURSOR-jait adja vissza úgy, hogy két típusparamétert OracleType.Cursor ad hozzá a OracleCommand.Parameters gyűjteményhez.

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;  

Az alábbi kód az előző parancs eredményeit adja vissza a parancs és NextResult() a Read() metódusok OracleDataReaderhasználatával. A REF CURSOR paramétereket a rendszer sorrendben adja vissza.

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

Az alábbi példa az előző parancsot használja az Oracle-csomag eredményeinek feltöltéséhez DataSet .

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

Feljegyzés

Az OverflowException elkerülése érdekében azt javasoljuk, hogy az Oracle NUMBER típusból érvényes .NET-keretrendszer típusra történő konvertálást is kezelje, mielőtt az értéket egy DataRow. Az esemény használatával FillError megállapíthatja, hogy történt-e overflowException . Az eseményről további információt a FillError DataAdapter-események kezelése című témakörben talál.

Lásd még