Опубликован: 07.05.2010 | Доступ: свободный | Студентов: 1678 / 62 | Оценка: 4.56 / 4.06 | Длительность: 34:11:00
Лекция 11:

Основы ADO.NET

Обработка множественного результирующего набора данных SqlDataReader

Команда SqlCommand.ExecuteReader() может возвращать множественный результирующий набор данных в двух случаях:

  1. Если вызывается хранимая процедура, содержащая несколько операторов SELECT
  2. Если выполняется строка SQL-запроса, содержащая несколько SQL-команд, разделенных точкой с запятой

Вот пример строки SQL-запроса, содержащей три команды SELECT:

string sql = "SELECT TOP 5 * FROM Employees;"
		+ "SELECT TOP 5 * FROM Customers;"
		+ "SELECT TOP 5 * FROM Suppliers";

Приведенная строка содержит три запроса, каждый из которых возвращает в результирующий набор данных по пять первых записей из трех таблиц базы Northwind. Ниже приведен код страницы, в котором выполняется последовательная выборка данных из множественного результирующего набора. Переход на новый результирующий набор выполняется методом NextResult(), который возвратит false, когда больше не останется результирующих наборов.

  • Создайте копию страницы TestDataReader.aspx с именем TestMultiDataReader.aspx и определите ее стартовой
  • Заполните страницу приведенным кодом
    <%@ Page Language="C#" %>
        
    <script runat="server">
        
        protected void Page_Load(object sender, EventArgs e)
        {
            // Извлекли строку соединения из web.config
            string connectString = System.Web.Configuration.WebConfigurationManager.
                ConnectionStrings["Northwind"].ConnectionString;
        
            // Создали объект соединения
            System.Data.SqlClient.SqlConnection con =
                new System.Data.SqlClient.SqlConnection(connectString);
        
            // Создали объект Command
            System.Data.SqlClient.SqlCommand cmd =
                new System.Data.SqlClient.SqlCommand();
        
            // Настроили объект Command
            cmd.Connection = con;
            cmd.CommandType = System.Data.CommandType.Text;
            cmd.CommandText = "SELECT TOP 5 * FROM Employees;"
    		                + "SELECT TOP 5 * FROM Customers;"
    		                + "SELECT TOP 5 * FROM Suppliers";
        
            System.Text.StringBuilder htmlStr = new StringBuilder("");
            int i = 0;
            
            using (con)
            {
                // Открыли соединение
                con.Open();
        
                // Выполняем команду и получаем результирующий набор данных
                System.Data.SqlClient.SqlDataReader reader =
                    cmd.ExecuteReader();
                
                // Перебираем частные наборы в результирующем наборе данных
                do
                {
                    htmlStr.Append("<h2>Набор: ");// Заголовок h2 HTML
                    htmlStr.Append(i.ToString());
                    htmlStr.Append("</h2>");
                    htmlStr.Append("<ul>"); // Начало маркированного списка
                    
                    // Перебираем все записи текущего набора
                    // (их должно по команде быть 5 первых)
                    // в результирующем наборе и строим HTML-строку
                    while (reader.Read())
                    {
                        htmlStr.Append("<li>");// Строка списка HTML
                        // Перебираем все поля строки набора
                        for (int field = 0; field < reader.FieldCount; field++)
                        {
                            if (field >= 3) // Ограничимся тремя первыми полями 
                                continue;
                            htmlStr.Append("<b>");
                            htmlStr.Append(reader.GetName(field).ToString());// Имя поля
                            htmlStr.Append(": </b>");
                            htmlStr.Append(reader.GetValue(field).ToString());// Значение поля
                            htmlStr.Append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");// Жесткие пробелы HTML
                        }
                        htmlStr.Append("</li>");
                    }
        
                    htmlStr.Append("</ul>"); // Конец маркированного списка
                    i++;
                    
                } while (reader.NextResult());
                
                // Закрываем набор данных
                reader.Close();
            }
        
            // Показываем пользователю результаты запроса
            lblInfo.Text = htmlStr.ToString();
        }
    </script>
        
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Label ID="lblInfo" runat="server" Text="Label"></asp:Label></div>
        </form>
    </body>
    </html>
  • Исполните страницу, должен получиться такой результат

Мы искусственно ограничили количество отображаемых полей тремя. Если этот оператор убрать, то на пользователя обрушится поток информации. Нам на данном этапе важен сам принцип извлечения информации из БД.

Если нам наплевать на пользователя и мы хотим показать ему извлеченные данные как они есть, без дополнительной обработки и форматирования, то можно воспользоваться элементом управления GridView. В этом случае необходимую страницу можно получить так:

  • Создайте копию страницы TestMultiDataReader.aspx с именем GridViewDataReader.aspx и определите ее стартовой
  • Поместите на страницу элемент управления GridView из вкладки Data панели Toolbox
  • Заполните страницу приведенным кодом
    <%@ Page Language="C#" %>
        
    <script runat="server">
        
        protected void Page_Load(object sender, EventArgs e)
        {
            // Извлекли строку соединения из web.config
            string connectString = System.Web.Configuration.WebConfigurationManager.
                ConnectionStrings["Northwind"].ConnectionString;
        
            // Создали объект соединения
            System.Data.SqlClient.SqlConnection con =
                new System.Data.SqlClient.SqlConnection(connectString);
        
            // Создали объект Command
            System.Data.SqlClient.SqlCommand cmd =
                new System.Data.SqlClient.SqlCommand();
        
            // Настроили объект Command
            cmd.Connection = con;
            cmd.CommandType = System.Data.CommandType.Text;
            cmd.CommandText = "SELECT TOP 5 * FROM Suppliers";
        
            using (con)
            {
                // Открыли соединение
                con.Open();
        
                // Выполняем команду и получаем результирующий набор данных
                System.Data.SqlClient.SqlDataReader reader =
                    cmd.ExecuteReader();
        
                // Подключаем элемент управления GridView
                // к полученному результирующему набору
                GridView1.DataSource = reader;
        
                // Наполняем элемент управления GridView
                // всеми извлеченными записями DataReader
                GridView1.DataBind();
        
                // Закрываем набор данных
                reader.Close();
            }
        }
    </script>
        
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:GridView ID="GridView1" runat="server">
                </asp:GridView>
            </div>
        </form>
    </body>
    </html>
  • Исполните страницу, должен получиться такой результат
SupplierID CompanyName ContactName ContactTitle Address City Region PostalCode Country Phone Fax HomePage
1 Exotic Liquids Charlotte Cooper Purchasing Manager 49 Gilbert St. London EC1 4SD UK (171) 555-2222
2 New Orleans Cajun Delights Shelley Burke Order Administrator P.O. Box 78934 New Orleans LA 70117 USA (100) 555-4822 #CAJUN.HTM#
3 Grandma Kelly's Homestead Regina Murphy Sales Representative 707 Oxford Rd. Ann Arbor MI 48104 USA (313) 555-5735 (313) 555-3349
4 Tokyo Traders Yoshi Nagase Marketing Manager 9-8 Sekimai Musashino-shi Tokyo 100 Japan (03) 3555-5011
5 Cooperativa de Quesos 'Las Cabras' Antonio del Valle Saavedra Export Administrator Calle del Rosal 4 Oviedo Asturias 33007 Spain (98) 598 76 54

Метод SqlCommand.ExecuteScalar()

Этот метод объекта Command возвращает скалярную величину типа Object, которая является результатом работы агрегатных функций вроде COUNT() или SUM() SQL-запроса. Чтобы получить конкретное значение, к возвращенному объекту нужно применить явное преобразование типов.

  • Создайте копию страницы TestConCommand.aspx с именем TestExecuteScalar.aspx и сделайте ее стартовой
  • Скорректируйте страницу TestExecuteScalar.aspx так
    <%@ Page Language="C#" %>
        
    <script runat="server">
        
        protected void Page_Load(object sender, EventArgs e)
        {
            // Извлекли строку соединения из web.config
            string connectString = System.Web.Configuration.WebConfigurationManager.
                ConnectionStrings["Northwind"].ConnectionString;
        
            // Создали объект соединения
            System.Data.SqlClient.SqlConnection con =
                new System.Data.SqlClient.SqlConnection(connectString);
        
            // Создали объект Command
            System.Data.SqlClient.SqlCommand cmd =
                new System.Data.SqlClient.SqlCommand();
        
            // Настроили объект Command
            cmd.Connection = con;
            cmd.CommandType = System.Data.CommandType.Text;
            cmd.CommandText = "SELECT COUNT(*) FROM Employees";
        
            using (con)
            {
                // Открыли соединение
                con.Open();
        
                // Выполнили команду подсчета записей таблицы Employees
                // с применением явного преобразования типа
                int recordCount = (int)cmd.ExecuteScalar();
        
                lblInfo.Text = "<b>Количество записей:</b> " + recordCount.ToString();
            }
        }
    </script>
        
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Label ID="lblInfo" runat="server" Text="Label"></asp:Label></div>
        </form>
    </body>
    </html>
  • Постройте страницу, результат будет таким

Метод SqlCommand.ExecuteNonQuery()

Этот метод напоминает консольную утилиту, которая работает в пакетном режиме, выполняет какие-либо действия, но не возвращает результатов. Метод ExecuteNonQuery() выполняет такие SQL-команды, как INSERT, DELETE, UPDATE, а возвращает только число, равное количеству обработанных записей.

В качестве примера приведем код страницы, удаляющий запись с определенным значением поля EmployeeID в таблице Employees БД Northwind. Поскольку эта база учебная, не будем ее портить и зададим заведомо несуществующее значение поля EmployeeID.

<%@ Page Language="C#" %>
    
<script runat="server">
    
    protected void Page_Load(object sender, EventArgs e)
    {
        // Формируем соединение
        string connectString = System.Web.Configuration.WebConfigurationManager.
            ConnectionStrings["Northwind"].ConnectionString;
        System.Data.SqlClient.SqlConnection con = 
            new System.Data.SqlClient.SqlConnection(connectString);
        
        // Формируем команду в конструкторе класса
        int empID = 111; // Заведомо несуществующее значение
        string sql = "DELETE FROM Employees WHERE EmployeeID = " + empID.ToString();
        System.Data.SqlClient.SqlCommand cmd = 
            new System.Data.SqlClient.SqlCommand(sql, con);
    
        try
        {
            con.Open();
            int recCount = cmd.ExecuteNonQuery();
            lblInfo.Text = string.Format("<b>Удалено записей:</b> {0}", recCount);
        }
        catch(System.Data.SqlClient.SqlException err)
        {
            lblInfo.Text = string.Format("<b>Ошибка удаления:</b> {0}", err.Message);
        }
        finally
        {
            con.Close();
        }
    }
</script>
    
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Label ID="lblInfo" runat="server" Text="Label"></asp:Label></div>
    </form>
</body>
</html>