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.