Российский Государственный Технологический Университет им. К.Э. Циолковского
Опубликован: 02.03.2007 | Доступ: свободный | Студентов: 5678 / 802 | Оценка: 3.96 / 3.45 | Длительность: 27:04:00
ISBN: 978-5-9556-0086-4
Лекция 18:

Основы ADO .NET

< Лекция 17 || Лекция 18: 123456789101112

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

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. Такой параметр должен быть первым в списке параметров.

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

Предложения SQLUpdate, 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();
< Лекция 17 || Лекция 18: 123456789101112
kewezok kewezok
kewezok kewezok
Елена Шляхт
Елена Шляхт
Объясните плиз в чем отличие а++ от ++а
Почему результат разный?
int a=0, b=0;
Console.WriteLine(a++); //0
Console.WriteLine(++b); //1
a++;
++b;
Console.WriteLine(a); //2
Console.WriteLine(b); //2