Číst v angličtině

Sdílet prostřednictvím


Načtení dat pomocí třídy DataReader

Chcete-li načíst data pomocí DataReader, vytvořte instanci command objektu a pak vytvořte DataReader voláním Command.ExecuteReader pro načtení řádků ze zdroje dat. DataReader poskytuje nerozbufferovaný datový proud dat, který umožňuje procedurální logiku efektivně zpracovávat výsledky ze zdroje dat postupně. Čtečka dat je dobrou volbou při načítání velkých objemů dat, protože data nejsou uložená v mezipaměti.

Následující příklad ukazuje použití DataReader, kde reader představuje platný DataReader a command představuje platný Command objekt.

reader = command.ExecuteReader();  

K získání řádku z výsledků dotazu použijte metodu DataReader.Read . Ke každému sloupci vráceného řádku můžete přistupovat předáním názvu nebo pořadového čísla sloupce do třídy DataReader. Pro zajištění nejlepšího výkonu však DataReader poskytuje řadu metod, které umožňují přístup k hodnotám sloupců v jejich nativních datových typech (GetDateTime, GetDouble, GetGuid, GetInt32 atd.). Seznam metod typového přístupového objektu pro objekty DataReader specifické pro zprostředkovatele dat naleznete OleDbDataReader a SqlDataReader. Použití metod typového přístupového objektu, pokud víte, že základní datový typ snižuje množství převodu typů vyžadované při načítání hodnoty sloupce.

Následující příklad iteruje objekt DataReader a vrátí dva sloupce z každého řádku.

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

Zavření čtečky dat

Vždy zavolat Close metoda po dokončení pomocí DataReader objektu.

Pokud příkaz obsahuje výstupní parametry nebo návratové hodnoty, nebudou tyto hodnoty k dispozici, dokud čtečka DatReader nezavře.

I když je čtečka dat otevřená, Připojení ion se používá výhradně pro tuto čtečku DatReader. Nelze spustit žádné příkazy pro Připojení ion, včetně vytvoření jiného objektu DataReader, dokud se původní čtečka DatReader neuzavře.

Poznámka

Nevolejte Close nebo Dispose na Připojení ion, DataReader ani žádný jiný spravovaný objekt v metodě Finalize vaší třídy. V finalizátoru uvolněte pouze nespravované prostředky, které vaše třída vlastní přímo. Pokud vaše třída nevlastní žádné nespravované prostředky, nezahrnujte do definice třídy metodu Finalize . Další informace naleznete v tématu Uvolňování paměti.

Načítání více sad výsledků pomocí nextResult

Pokud DataReader vrátí více sad výsledků, zavolejte NextResult metoda iterovat přes sady výsledků postupně. Následující příklad ukazuje SqlDataReader zpracování výsledků dvou příkazů SELECT pomocí ExecuteReader metody.

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

Získání informací o schématu ze třídy DataReader

Zatímco DataReader je otevřen, můžete načíst informace o schématu o aktuální sadě výsledků pomocí GetSchemaTable metoda. Funkce GetSchemaTable vrátí DataTable objekt naplněný řádky a sloupci, které obsahují informace o schématu pro aktuální sadu výsledků. Tabulka DataTable obsahuje jeden řádek pro každý sloupec sady výsledků. Každý sloupec tabulky schématu se mapuje na vlastnost sloupců vrácených v řádcích sady výsledků, kde ColumnName je název vlastnosti a hodnota sloupce je hodnota vlastnosti. Následující příklad zapíše informace o schématu pro DataReader.

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

Práce s kapitolami OLE DB

Hierarchické sady řádků nebo kapitoly (typ OLE DB DBTYPE_HCHAPTER, adChapter typu ADO) lze načíst pomocí .OleDbDataReader Pokud je dotaz, který obsahuje kapitolu, vrácen jako DataReader, kapitola je vrácena jako sloupec v objektu DataReader a je vystavena jako Objekt DataReader .

Datovou sadu ADO.NET lze také použít k reprezentaci hierarchických sad řádků pomocí relací nadřazených a podřízených mezi tabulkami. Další informace naleznete v tématu Datové sady, Datové tabulky a DataViews.

Následující příklad kódu používá zprostředkovatel MSDataShape k vygenerování sloupce kapitol objednávek pro každého zákazníka v seznamu zákazníků.

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

Vrácení výsledků pomocí Oracle REF CURSORs

Rozhraní .NET Framework Zprostředkovatel dat pro Oracle podporuje použití oracle REF CURSORs k vrácení výsledku dotazu. Oracle REF CURSOR je vrácen jako OracleDataReader.

Pomocí metody můžete načíst OracleDataReader objekt, který představuje Oracle REF CURSOR ExecuteReader . Můžete také určit OracleCommand , který vrátí jeden nebo více Oracle REF CURSORs jako SelectCommand pro OracleDataAdapter použití k vyplnění DataSet.

Pokud chcete získat přístup k REF CURSOR vrácený ze zdroje dat Oracle, vytvořte OracleCommand pro svůj dotaz a přidejte výstupní parametr, který odkazuje NA REF CURSOR na Parameters kolekci vašeho OracleCommand. Název parametru se musí shodovat s názvem parametru REF CURSOR v dotazu. Nastavte typ parametru na OracleType.Cursorhodnotu . Metoda OracleCommand.ExecuteReader() vrátí OracleCommand OracleDataReader pro REF CURSOR.

Pokud vrátíte OracleCommand více REF CURSORS, přidejte více výstupních parametrů. K různým objektům REF CURSORs se dostanete voláním OracleCommand.ExecuteReader() metody. Volání, které ExecuteReader() vrátí OracleDataReader odkaz na první REF CURSOR. Pak můžete volat metodu OracleDataReader.NextResult() pro přístup k následným REF CURSORs. Přestože parametry v OracleCommand.Parameters kolekci odpovídají výstupním parametrům REF CURSOR podle názvu, OracleDataReader přistupuje k nim v pořadí, v jakém byly přidány do Parameters kolekce.

Představte si například následující balíček Oracle a text balíčku.

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;

Následující kód vytvoří OracleCommand , který vrátí REF CURSORs z předchozího balíčku Oracle přidáním dvou parametrů typu OracleType.Cursor do OracleCommand.Parameters kolekce.

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;  

Následující kód vrátí výsledky předchozího příkazu pomocí Read() metod NextResult() a metod OracleDataReader. Parametry REF CURSOR se vrátí v pořadí.

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

Následující příklad používá předchozí příkaz k naplnění DataSet výsledků balíčku Oracle.

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

Poznámka

Chcete-li zabránit overflowException, doporučujeme, abyste před uložením hodnoty do DataRowsouboru .NET Framework zpracovávali také jakýkoli převod z typu Oracle NUMBER na platný typ rozhraní .NET Framework. Událost můžete použít FillError k určení, zda došlo k overflowException . Další informace o FillError události naleznete v tématu Zpracování událostí dataAdapter.

Viz také