2007 г.
Марченко Антон Леонардович
Интернет-Университет Информационных Технологий, INTUIT.ru
Назад Оглавление Вперёд
Свойства параметров
Parameter является достаточно сложной конструкцией, о чем свидетельствует НЕПОЛНЫЙ список его свойств:
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
или InputOutput
(если параметр используется в процедуре как для получения, так и для отправления значений). Очевидно, что тип параметра должен соответствовать ожидаемому возвращаемому значению.
После выполнения процедуры можно прочитать значение возвращаемого параметра.
- Непосредственный перехват возвращаемого значения сохраняемой процедурой.
Для этого следует создать параметр с Direction
-свойством, установленным в ReturnValue
. Такой параметр должен быть первым в списке параметров.
При этом тип параметра должен соответствовать ожидаемому возвращаемому значению.
Предложения SQL – Update, Insert, and Delete
возвращают целочисленное значение, соответствующее количеству записей, на которые повлияло выполнение данного предложения.
Это значение может быть получено как возвращаемое значение метода ExecuteNonQuery
.
Следующий пример демонстрирует, как получить возвращаемое значение, возвращаемое хранимой процедурой CountAuthors
. В этом случае предполагается, что первый параметр списка параметров конфигурируется как возвращаемый:
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.Execute Reader
возвращает ссылку на SqlDataReader, OleDbCommand.Execute Reader
возвращает ссылку на 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();
Использование объекта 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
под именем myOleDb Command
. Свойство Connection
этого объекта определяет соединение с именем myConnection
.
Итак:
// Активное соединение открыто.
MyConnection.Open();
System.Data.OleDb.OleDbDataReader myReader = myOleDbCommand.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine(myReader["Customers"].ToString());
}
myReader.Close();
// Активное соединение закрыто.
MyConnection.Close();
Назад Оглавление Вперёд