Файл: 1_C#_Введение_в_программирование_Уч_пособ_(Марченко-2005).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 11.12.2025

Просмотров: 1388

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Оба типа объектов Команда (SqlCommand и OleDbCommand) поддерживают три метода, которые позволяют исполнять представляемую команду:

ExecuteNonQuery – применятся для выполнения команд SQL и хранимых процедур, таких, как INCERT, UPDATE, DELETE. С помощью этого метода также выполняются команды DDL – CREATE, ALTER. Не возвращает никаких значений

ExecuteScalar – обеспечивает выбор строк из таблицы БД. Возвращает значение первого поля первой стоки, независимо от общего количества выбранных строк.

ExecuteReader - обеспечивает выбор строк из таблицы БД. Возвращает неизменяемый объект DataReader, который допускает последовательный однонаправленный просмотр извлечённых данных без использования объекта

DataAdapter.

Кроме того, класс SqlCommand поддерживает ещё один метод -

ExecuteXmlReader - обеспечивает выбор строк из таблицы БД в формате XML. Возвращает неизменяемый объект XMLReader, который допускает последовательный однонаправленный просмотр извлечённых данных.

Назначение всех четырёх методов – ИСПОЛНЕНИЕ НА ИСТОЧНИКЕ ДАННЫХ команды, представленной объектом команды.

Parameter

Данные из базы выбираются в разультате выполнения объекта Command. В ADO.NET применяются параметризованные команды. Объект Parameter является средством модификации команд. Представляет свойства и методы, позволяющие определять типы данных и значения параметров.

Настройка команд

Манипулирование данными, которое осуществляется в процессе выполнения команд, естественно, требует определённой информации, которая представляется в команде в виде параметров. При этом характер и содержание управляющей дополнительной информации зависит от конкретного состояния базы на момент выполнения приложения.

Это означает, что настройка команды должна быть проведена непосредственно в процессе выполнения приложения. Именно во время выполнения приложения определяются конкретные значения параметров, проводится соответствующая настройка команд и их выполнение.

В структуре команды предусмотрены так называемые ПОЛЯ ПОДСТАНОВКИ. Объект команды при выполнении приложения настраивается путём присвоения значения параметра полю подстановки. Эти самые поля подстановки реализованы в виде свойства Parameters объекта команды. В зависимости от типа провайдера каждый параметр представляется объектом одного из классов: OleDbParameter или

SqlParameter.

Необходимое количество параметров для выполнения той или иной команды зависит от конкретных обстоятельств: каждый параметр команды представляется собственным объектом-параметром. Кроме того, если команда представляется сохраняемой процедурой, то может потребоваться дополнительный объект-параметр.

Во время выполнения приложения объект команды предварительно настраивается путём присваивания свойству Parameters списка (вполне возможно, что состоящего из одного элемента) соответствующих значений параметров – объектов класса Parameters. При выполнении команды эти значения параметров считываются и либо непосредственно подставляются в шаблон оператора языка SQL, либо передаются в качестве параметров хранимой процедуре.

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

Кроме того, работа с конкретной СУБД также накладывает свою специфику на правила формирования объекта команды.

Свойства параметров

Parameter является достаточно сложной конструкцией, о чём свидетельствует НЕПОЛНЫЙ список его свойств:

247


Value – свойство, предназначенное для непосредственного сохранения значения параметра.

Direction – свойство объекта-параметра, которое определяет, является ли параметр входным или выходным. Множество возможных значений представляется следующим списком: Input, Output, InputOutput, ReturnValue.

DbType (не отображается в окне дизайнера) в сочетании с OleDbType (только для объектов типа OleDbParameters) – параметры, используемые для согласования типов данных, принятых в CTS (Common Type System) и типов, используемых в конкретных базах данных.

DbType (не отображается в окне дизайнера) в сочетании с SQLType (только

для

объектов типа SqlParameters) - параметры, также используемые

для

согласования

типов данных, принятых в CTS (Common Type System) и типов,

используемых

в конкретных базах данных,

 

ParameterName – свойство, которое обеспечивает обращение к данному элементу списка параметров команды непосредственно по имени, а не по индексу. Разница между этими двумя стилями обращения к параметрам демонстрируется в следующем фрагменте кода:

OleDbCommand1.Parameters[0].Value = “OK”;

//В команде, представляемой объектом OleDbCommand1, значение первого

//элемента списка параметров есть строка “OK”. OleDbCommand1.Parameters[“ParameterOK”].Value = “OK”;

//В команде, представляемой объектом OleDbCommand1, значение элемента

//списка параметров, представленного именем “ParameterOK”,

//есть строка “OK”.

Precision, Scale, Size определяют длину и точность соответствующих параметров. При этом первые два свойства применяются для задания разрядности и длины дробной части значения параметров таких типов как float, double, decimal, последнее свойство используется для указания максимально возможной длины строкового и двоичного параметра.

Установка значений параметров

Следующий пример показывает, как установить параметры перед выполнением команды, представленной хранимой процедурой. Предполагается, что уже была собрана соответствующая последовательность параметров, с именами au_id, au_lname, и au_fname.

OleDbCommand1.CommandText = “UpdateAuthor”; OleDbCommand1.CommandType = System.Data.CommandType.StoredProcedure; OleDbCommand1.Parameters[”au_id”].Value = listAuthorID.Text; OleDbCommand1.Parameters[”au_lname”].Value = txtAuthorLName.Text; OleDbCommand1.Parameters[”au_fname”].Value = txtAuthorFName.Text; OleDbConnection1.Open();

OleDbCommand1.ExecuteNonQuery();

OleDbConnection1.Close();

Получение возвращаемого значения

Сохраняемые процедуры могут обеспечить передачу возвращаемого значения функции приложения, которое обеспечило их вызов. Это передача может быть обеспечена непосредственно параметром при установке свойства Direction

параметра

в Output

или InputOutput, либо за счёт непосредственного

возвращения

значения

сохраняемой процедурой, при котором используется

параметр со свойством, установленным в ReturnValue. Получение значений, возвращаемых сохраняемой процедурой.

Использование параметра

Для этого следует создать параметр с Direction свойством, установленным в Output or InputOutput (если параметр используется в процедуре как для получения, так и для отправления значений). Очевидно, что тип параметра должен соответствовать ожидаемому возвращаемому значению.

After executing the procedure, read the Value property of the parameter being passed back. Такие вот дела…

Непосредственный перехват возвращаемого значения сохраняемой процедурой

248


Для этого следует создать параметр с Direction свойством, установленным в

ReturnValue.

Важно! Такой параметр должен быть первым в списке параметров.

При этом тип параметра должен соответствовать ожидаемому возвращаемому значению.

Важно! Предложения SQL - Update, Insert, and Delete возвращают целочисленное значение, соответствующее the number of records affected by the statement.

Это значение может быть получено как возвращаемое значение метода

ExecuteNonQuery.

Следующий пример демонстрирует, как получить возвращаемое значение,

возвращаемое хранимой процедурой CountAuthors. In this case, it is assumed that the first parameter in the command’s Parameters collection is named “retvalue” and that is configured with a direction of ReturnValue.

int cntAffectedRecords;

//The CommandText and CommandType properties can be set

//in the Properties window but are shown here for completeness. oleDbcommand1.CommandText = “CountAuthors”; oleDbCommand1.CommandType = CommandType.StoredProcedure; oleDbConnection1.Open();

oleDbCommand1.ExecuteNonQuery();

oleDbConnection1.Close();

cntAffectedRecords = (int)(OleDbCommand1.Parameters[”retvalue”].Value); MessageBox.Show(“Affected records = “ + cntAffectedRecords.ToString());

DataReader

Компонента провайдера, объект-представитель (варианта) класса DataReader. Предоставляет подключённый к источнику данных набор записей, доступный лишь

для однонаправленного чтения.

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

доступа

к значениям столбцов

используется свойство Item, обеспечивающее

доступ к

столбцу по его индексу

(то есть, ИНДЕКСАТОР!).

При этом метод GetOrdinal объекта-представителя класса DataReader принимает строку с именем столбца и возвращает целое значение, соответствующее индексу столбца.

Непосредственно обращением к конструктору эту компоненту провайдера созать нельзя. Этим DataReader отличается от других компонентов провайдера данных.

Объект DataReader создаётся в результате обращения к одному из вариантов метода ExecuteReader объекта Command (SqlCommand.ExecuteReader возвращает ссылку на SqlDataReader, OleDbCommand.ExecuteReader возвращает ссылку на OleDbDataReader).

То есть, выполняется команда (например, запрос к базе данных), а соответствующий результат получается при обращении к объекту-представителю класса DataReader.

Метод ExecuteReader возвращает множество значений как ОДИН ЕДИНСТВЕННЫЙ ОБЪЕКТ – объект-представитель класса DataReader. Остаётся только прочитать данные.

Выполняется запрос, получается объект-представитель класса DataReader, который позволяет перебирать записи результирующего набора и… ПЕРЕДАВАТЬ НУЖНЫЕ ЗНАЧЕНИЯ КОДУ ПРИЛОЖЕНИЯ.

При этом DataReader обеспечивает чтение непосредственно из базы. И потому требует монопольного доступа к активному соединению. DataReader реализован без излишеств. Только ОДНОНАПРАВЛЕННОЕ чтение! Любые другие варианты его использования невозможны.

// Создание объектов DataReader. Пример кода. System.Data.OleDb.OleDbCommand myOleDbCommand; System.Data.OleDb.OleDbDataReader myOleDbDataReader; myOleDbDataReader = myOleDbCommand.ExecuteReader();

System.Data.SqlClient.SqlCommand mySqlCommand; System.Data.SqlClient.SqlDataReader mySqlDataReader; mySqlDataReader = mySqlCommand.ExecuteReader();

249


Использование объекта DataReader

Обеспечение так называемого “доступа к ОТСОЕДИНЁННЫМ данным” – заслуга объекта DataReader. Дело в том, что получение данных приложением из базы данных всё равно требует установления соединения. И это соединение должно быть максимально коротким по продолжительности и эффективным. Быстро соединиться, быстро прочитать и запомнить информацию из базы, быстро разъединиться. Именно для этих целей используется в ADO.NET объект DataReader.

После получения ссылки на объект DataReader, можно организовать просмотр записей. Для получения необходимой информации из базы данных этого достаточно.

У объекта DataReader имеется “указатель чтения”, который устанавливается на первую запись результирующего набора записей, который образовался в результате выполнения метода ExecuteReader(). Очередная (в том числе и первая) запись набора становится доступной в результате выполнения метода Read().

Вслучае успешного выполнения этого метода указатель переводится на следующий элемент результирующей записи, а метод Read() возвращает значение true.

Впротивном случае метод возвращает значение false. Всё это позволяет

реализовать очень простой и эффективный механизм доступа к данным. Например, в рамках цикла while.

Если иметь в виду, что каждая запись состоит из одного и того же количества полей, которые к тому же имеют различные идентификаторы, то, очевидно, что доступ к значению отдельного поля становится возможным через индексатор, значением которого может быть как значение индекса, так и непосредственно обозначающий данное поле идентификатор.

while (myDataReader.Read())

{

object myObj0 = myDataReader[5];

object myObj1 = myDataReader[“CustomerID”];

}

Важно!

При таком способе доступа значения полей представляются ОБЪЕКТАМИ. Хотя, существует возможность получения от DataReader’а и типизированных значений.

Следует иметь в виду, что DataReader удерживает монопольный доступ к активному соединению. Вот как всегда! Пообещали отсоединённый доступ к данным, а получаем постоянное соединение! Закрывается соединение методом Close()

myDataReader.Close();

Можно также настроить DataReader таким образом, чтобы закрытие соединения происходило автоматически, без использования команды Close(). Для этого при вызове метода ExecuteReader свойство объекта команды CommandBehavior должно быть выставлено в CloseConnection.

Пример. Выборка столбца таблицы с помощью объекта DataReader. Предполагается наличие объкта OleDbCommand под именем myOleDbCommand. Свойство Connection этого объекта определяет соединение с именем myConnection.

Итак:

//Активное соединение открыто. MyConnection.Open();

System.Data.OleDb.OleDbDataReader myReader = myOleDbCommand.ExecuteReader(); while (myReader.Read())

{

Console.WriteLine(myReader[”Customers”].ToString());

}

myReader.Close();

//Активное соединение закрыто.

MyConnection.Close();

Извлечение типизированных данных

Среди множества методов классов DataReader (SqlDataReader и OleDbDataReader)

около десятка методов, имена который начинаются с приставки Get… следом за которой – имя какого-то типа. GetInt32, GetBoolean, …

250