Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция4.doc
Скачиваний:
23
Добавлен:
01.05.2025
Размер:
212.99 Кб
Скачать

Использование DataSets и DataReaders:

DataSet

DataReader

Создание связей базы данных

Создание связей базы данных

Сохранение в DataAdapter

Открыть соединение с базой данных

Заполнение DataSet с помощью метода Fill()

Сохранить запрос в SqlCommand

Создать объект DataView

Заполнение DataReader с помощью метода ExecuteReader ()

Привязка DataView к списку управления с привязкой

Вызвать Read для каждой записи, и Get для каждого поля

Отображение данных вручную

Закрыть DataReader и соединение

Общая процедура доступа к базам данных из ADO.NET отличается в зависимости от того, будет использоваться DataSet или DataReader:

Использование DataSet

Использование DataReader

1. Подключение к базе данных с помощью SqlConnection или OleDbConnection

1. Подключение к базе данных с помощью SqlConnection или OleDbConnection.

2. Сохранение запроса к базе данных в объектах SqlDataAdapter или OleDbDataAdapter.

2. Открыть связи с помощью метода Open.

3. Заполнение DataSet из DataAdapter с помощью Fill.

3. Сохранение запроса к базе данных в объекты SqlCommand или OleDbCommand.

4. Установление нового DataView для необходимой таблицы.

4. Заполнение DataReader из Command с помощью метода ExecuteReader().

5. Привязка серверного элемента управления такого как DataGrid для DataView.

5. Вызвать методы Read и Get объекта DataReader для чтения данных.

6. Отображение данных вручную.

7. Закрыть DataReader и соединение.

Получение множества наборов результатов с помощью объектов чтения данных.

Объекты чтения данных могут получать от одного объекта команды множество наборов результатов (из разных таблиц БД). Например, чтобы получить все строки таблицы «Друзья» и все строки таблицы «Информация о друзьях», можно указать оба соответствующих SQL-оператора, используя в качестве разделителя точку с запятой (если имя поля состоит из нескольких слов, то в SQL-операторе его нужно заключать в квадратные скобки). Получив объект чтения данных, можно переходить от одного результирующего набора к другому с помощью метода NextResult(). При этом возвращение к первому набору происходит автоматически:

/////// Получение двух наборов результатов:

cn.Open();

string theSQL = "Select * From Друзья; Select * From [Информация о друзьях]";

SqlCommand mycomm = new SqlCommand(theSQL, cn);

Console.WriteLine(mycomm.CommandText);

try

{

myReader = mycomm.ExecuteReader();

do

{

while (myReader.Read())

{

Console.WriteLine("***** Запись таблиц Друзья и Информация о друзьях: *****");

for (int i = 0; i < myReader.FieldCount; i++)

Console.WriteLine(" {0}= {1}", myReader.GetName(i), myReader.GetValue(i).ToString().Trim());

Console.WriteLine();

}

} while (myReader.NextResult());

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

finally

{

if (myReader != null)

myReader.Close();

if (cn.State == ConnectionState.Open)

cn.Close();

Console.WriteLine("Состояние соединения " + cn.State.ToString());

}

Объекты параметризованных команд. В приведенных примерах каждый SQL-оператор представлен «жестко» закодированными строковыми литералами. С SQL-параметрами можно обращаться, как с объектами, а не с простыми строками текста, если использовать параметризованные запросы. Параметризованные запросы выполняются намного быстрее буквальных SQL-строк, поскольку они анализируются только один раз (а не каждый раз, когда SQL-строка присваивается свойству CommandText).

Объекты команд ADO.NET поддерживают коллекцию дискретных типов параметра. По умолчанию эта коллекция пуста, но в нее можно добавить любое число параметров объекта, которые должны будут отображаться в «заместитель» параметра в SQL–запросе. Чтобы ассоциировать параметр в SQL–запросе с членом коллекции параметров данного объекта команды, к текстовому SQL–параметру добавляют префикс @.

Рассмотрим тип DbParametr, который является базовым классом объектов параметров, специфичных для конкретного поставщика данных (например, SQL Server.NET Data Provider). Этот класс поддерживает ряд свойств, позволяющих указать имя, размер, тип данных параметра.

Таблица. Свойства класса DbParameter

Свойство

Описание

DataType

Определяет тип параметра в терминах .NET

DbType

Позволяет получить или задать тип данных, используемый в источнике данных.

Direction

Определяет, будет ли этот параметр передаваться в источник данных, возвращаться с источника данных или он сможет использоваться для передачи и в том, и в другом направлении.

IsNullable

Позволяет определить, будет ли данный параметр допускать пустые значения (значения типа NULL).

ParameterName

Позволяет получить или установить имя (DbParametr) параметра.

Precision

Позволяет получить или установить максимальное количество цифр, используемых для значения параметра (определяемое через свойство Value).

Scale

Позволяет получить или установить количество десятичных разрядов, используемых для значения параметра.

Size

Позволяет получить или установить максимальный размер данных для данного параметра.

Value

Позволяет получить или установить значение параметра.

Создадим параметризованный SQL-запрос, который вставляет новую запись в таблицу «Друзья»:

Console.WriteLine("Создание параметризованного запроса:");

// Сбор информации о новом друге:

Console.WriteLine("Введите код друга!");

int kod_dr = Int32.Parse(Console.ReadLine());

Console.WriteLine("Введите фамилию друга!");

string fam_dr = Console.ReadLine();

Console.WriteLine("Введите отчество друга!");

string ot_dr = Console.ReadLine();

Console.WriteLine("Введите имя друга!");

string imja_dr = Console.ReadLine();

// Создание и формирование параметризованного sql-запроса:

string sqlPar = string.Format("Insert Into Друзья" + "([Код друга], Фамилия, Отчество, Имя) Values" + "(@Код, @Фамилия,@Отчество,@Имя)");

// Имена параметров должны состоять из одного слова! К ним нельзя применять []!!!.

SqlCommand cmdPar = new SqlCommand(sqlPar, cn);

//Наполнение коллекции параметров:

SqlParameter param = new SqlParameter();

param.ParameterName = "@Код";

param.Value = kod_dr;

param.SqlDbType = SqlDbType.Int;

cmdPar.Parameters.Add(param);

param = new SqlParameter();

param.ParameterName = "@Фамилия";

param.Value = fam_dr;

param.SqlDbType = SqlDbType.Char;

param.Size = 20;

cmdPar.Parameters.Add(param);

param = new SqlParameter();

param.ParameterName = "@Отчество";

param.Value = ot_dr;

param.SqlDbType = SqlDbType.Char;

param.Size = 15;

cmdPar.Parameters.Add(param);

param = new SqlParameter();

param.ParameterName = "@Имя";

param.Value = imja_dr;

param.SqlDbType = SqlDbType.Char;

param.Size = 15;

cmdPar.Parameters.Add(param);

Console.WriteLine(cmdPar.CommandText);

try { cmdPar.ExecuteNonQuery(); }

catch (SqlException e) { Console.WriteLine(e.Message); }

Наиболее полезными параметризованные запросы оказываются при запуске хранимых процедур.

Хранимые процедуры. Хранимой процедурой называется одна или несколько SQL-конструкций, которые записаны в базе данных. Задача администрирования базы данных включает в себя в первую очередь распределение уровней доступа к БД. Разрешение выполнения обычных SQL-запросов большому числу пользователей может стать причиной неисправностей из-за неверного запроса или их группы. Чтобы этого избежать, разработчики базы данных могут создать ряд хранимых процедур для работы с данными и полностью запретить доступ для обычных запросов. Такой подход при прочих равных условиях обеспечивает большую стабильность и надежность работы. Это одна из главных причин создания собственных хранимых процедур. Другие причины – быстрое выполнение, разбиение больших задач на малые модули, уменьшение нагрузки на сеть – значительно облегчают процесс разработки и обслуживания архитектуры «клиент – сервер».

Перейдем к созданию своих собственных хранимых процедур. Создадим новый бланк запросов (New Query в контекстном меню базы данных), либо в Server Explorer выбрать в контекстном меню объекта Stored Procedures команду Add New Stored Procedure и введем следующий запрос:

create procedure proc1 as

select [Код туриста], Фамилия, Имя, Отчество from Туристы

Здесь create procedure – оператор, указывающий на создание хранимой процедуры, proc1 – ее название, далее после оператора as следует обычный SQL-запрос. Квадратные скобки необходимы для указания поля таблицы, в названии которого содержится пробел. После выполнения запроса (развернуть ветку «Хранимые процедуры» в среде Management Express и выбрать команду Execute) появится сообщение:

Выполнение команд успешно завершено.

The COMMAND(s) completed successfully.

Вначале появляется шаблон структуры, сгенерированный мастером:

CREATE PROCEDURE dbo.StoredProcedure1

/*

(

@parameter1 int = 5,

@parameter2 datatype OUTPUT

)

*/

AS

/* SET NOCOUNT ON */

RETURN

Для того чтобы приступить к редактированию, достаточно убрать знаки комментариев «/*», «*/». Команда NOCOUNT со значением ON отключает выдачу сообщений о количестве строк таблицы, получающейся в качестве запроса. Необходимость данного оператора заключается в том, что при использовании более чем одного оператора (SELECT, INSERT, UPDATE или DELETE) в начале запроса надо поставить команду SET NOCOUNT ON, а перед последним оператором SELECT – команду SET NOCOUNT OFF.

Например, хранимую процедуру proc_po1 можно переписать следующим образом:

CREATE PROCEDURE dbo.proc_vs1

(

@TouristID int,

@LastName nvarchar(60) OUTPUT

)

AS

SET NOCOUNT ON

SELECT @LastName = Фамилия

FROM Туристы

WHERE ([Код туриста] = @TouristID)

RETURN

После завершения редактирования SQL-конструкция будет обведена синей рамкой. Щелкнув правой кнопкой в этой области и выбрав пункт меню «Разработать блок SQL» («Design SQL Block»), можно перейти к построителю запросов (Query Builder). Для выполнения процедуры необходимо в выпадающем меню процедуры выбрать пункт Execute.

Чтобы выполнить хранимую процедуру в программном коде приложения, следует, как всегда, сначала создать новый объект соединения, сформировать строку соединения и открыть сеанс. При создании объекта команды свойству CommandText нужно присвоить имя хранимой процедуры, а не SQL-запроса. Также нужно установить для свойства CommandType значение CommandType.StoredProcedure.

//SqlCommand com = new SqlCommand("proc1", cn);

//com.CommandType = CommandType.StoredProcedure;

//com.ExecuteNonQuery();

На практике часто возникает потребность получить информацию из БД по некоторому заданному значению «входных» данных (параметру) запроса. Такие запросы называются параметризированными, а соответствующие процедуры создаются с параметрами. Например, для получения записи в таблице «Туристы» по заданной фамилии создадим следующую процедуру:

create proc proc_p1

@Фамилия nvarchar(50)

as

select *

from Туристы

where

Фамилия=@Фамилия

После знака @ указывается название параметра и его тип. Таким образом, для параметра с именем Фамилия был выбран тип nvarchar c количеством символов 50, поскольку в самой таблице для поля «Фамилия» установлен этот тип.

Попытка запустить процедуру командой exec proc_p1 приводит к появлению сообщения об отсутствующем параметре. Процедуру необходимо запускать следующим образом:

exec proc_p1 'Андреева'