Программирование в IIS

       

Запись в базу данных


Реализация функций CreateChair и OpenChair требует взаимодействия с базой данных. Функция CreateDir вставляет данные о новом объекте "стул" в базу данных, в OpenChair заполняет состояние экземпляра класса значениями, считанными из базы данных. Функция Createchair генерирует для этого объекта идентификатор ID, создает команду SQL и записывает новые значения в базу данных при помощи выражения SQL INSERT. В листинге 1.7 приведен код функции CreateChair.

Листинг 1.7. Function CreateChair (html, txt)

При вызове функции CreateNewID генерируется новый ID объекта "стул". CreateNewID вызывает функцию New(), форматирует значение в виде уникального числа и преобразует его в строку. В листинге 1.8 приведен исходный код функции CreateNewID. Данный алгоритм имеет большой недостаток. Он генерирует уникальную строку ID только в том случае, если запрос выполняется через 1 с после предыдущего запроса ID. Для получения уникальных значений необходимы более приемлемые подходы, например, использование функции глобально уникального идентификатора Windows (GUID) или других самодельных функций с генератором случайных чисел. Этот недостаток не был устранен, чтобы класс clsChair стабильно генерировал ошибку при записи информации в базу данных. Ошибка возникает из-за того, что ID объекта "стул" является главным ключом в таблице базы данных, в которой находится информация об этом объекте. Запись строки, содержащей такое же значение ID, что и записанное ранее, приведет к ошибке обновления ADO.

Листинг 1.8. Function CreateNewID (html, txt)

После генерации ID конструируется выражение SQL с использованием констант, являющихся частью выражения обновления SQL, с помощью которого новые данные записываются в базу данных. Использованное значение color в действительности является локальным значением m_scolor. Свойство color, как и me.color, можно (и нужно) использовать вместо локального значения m_scolor. Если свойство color нужно подтвердить или изменить из его текущего состояния в экземпляре класса, то оно пригодится для внесения небольшого изменения в код в единственном месте, однако в этом случае потребуется изменить код и в свойстве, и в функции при помощи переменной m_scolor.


После построения команды SQL функция ExecuteCommand передает эту команду в базу данных для выполнения (см. листинг 1.9). В этой функции не предусмотрен возврат значения от события. При выполнении операции ExecuteCommand использует ADO.

Для работы с технологией ADO в набор ссылок проекта ConfigSeat нужно добавить ссылку на ADO. ADO инсталлируется при помощи пакета Microsoft Data Access Components (MDAC). ADO присутствует в ссылках Visual Basic как библиотека ActiveX Data Objects x Library, где x – номер версии MDAC. На момент написания данной книги последней версией пакета была версия 2.7, но можно использовать и версию 2.6. Если программное обеспечение располагается на узле с NT 4, то нужно использовать версию 2.6.

Листинг 1.9. Function ExecuteCommand (html, txt)

В большей части вызовов Err.Raise, выполняемых при возникновении исключительных ситуаций, выводится номер ошибки 1001. Можно указать любой номер, однако это число выбрано для простоты. Используйте числа из диапазона 1000 – 65535, предназначенного для нумерации особых ошибок. Объект ADO Command предназначен для вызова сервера базы данных. Если от объекта Command ожидается набор записей Recordset, то функция Execute возвращает набор записей ADO Recordset. Так как объект ExecuteCommand изначально не предназначен для возврата набора записей Recordset, объект Recordset, возвращаемый от объекта Command, игнорируется.

ExecuteCommand проверяет, что локальный объект подключения m_Connection установлен и жизнеспособен. После этого создается объект Command и настраивается на отправку серверу команды SQL. Если во время выполнения ExecuteCommand возникнет ошибка, обработчик ошибок зафиксирует ее и выйдет из функции, возвратив значение "ложь". Все переменные типа boolean в VB имеют значение "ложь", если им не присвоены иные значения, поэтому включите в программу код, присваивающий функции значение "истина" по достижении успеха.

Функция OpenChair открывает набора записей ADO Recordset по известному ID объекта "стул", переданного функции, и заполняет экземпляр класса по результатам перемещения к первой записи набора Recordset.


В листинге 1. 10 приведен исходный код функции OpenChair. Так как ID объекта "стул" является уникальным в базе данных, то ввиду ограничений работы с данными безопаснее считать, что функция возвращает только одну строку данных, и, как правило, следует использовать именно первую строку. Recordset исследуется на наличие данных с помощью проверки BOF (начало файла) и EOF (конец файла) – они не должны равняться значению "истина". Если значение параметров BOF и EOF равно "истине", то в наборе Recordset записи отсутствуют. Выполнение команды MoveFirst в пустом наборе Recordset приведет к ошибке. Свойства EOF или BOF всегда проверяются перед прохождением по набору Recordset в одном из направлений при помощи команд MoveNext или MovePrevious.

Листинг 1.10. Function OpenChair (html, txt)

Набор Recordset, полученный для OpenChair, создан другой вспомогательной ADO-функцией – GetADORecordSet. Как и ExecuteCommand, GetADORecordSet воспринимает выражение SQL как параметр и открывает набор Recordset из источников данных в локальном экземпляре m_Connection объекта Connection. Объект набора записей передается в вызывающую функцию. В листинге 1.11 приведен исходный код функции GetADORecordSet.

Листинг 1.11. Function GetADORecordSet (html, txt)

Существует много возможностей по усовершенствованию функции GetADORecordSet. Одной из них является установка набора ADO Recordset как параметра функции, передаваемого в ByRef, и возврат значения "истина" или "ложь" в зависимости от результата извлечения набора Recordset. Программа расходует ресурсы на создание набора записей ADO Recordset только один раз, и функция сообщит вызывающей функции о правильности набора Recordset. Функции ExecuteCommand и GetADORecordSet можно объединить в одну.



Можно указать любой номер, однако это число выбрано для простоты. Используйте числа из диапазона 1000 – 65535, предназначенного для нумерации особых ошибок. Объект ADO Command предназначен для вызова сервера базы данных. Если от объекта Command ожидается набор записей Recordset, то функция Execute возвращает набор записей ADO Recordset. Так как объект ExecuteCommand изначально не предназначен для возврата набора записей Recordset, объект Recordset, возвращаемый от объекта Command, игнорируется.

ExecuteCommand проверяет, что локальный объект подключения m_Connection установлен и жизнеспособен. После этого создается объект Command и настраивается на отправку серверу команды SQL. Если во время выполнения ExecuteCommand возникнет ошибка, обработчик ошибок зафиксирует ее и выйдет из функции, возвратив значение "ложь". Все переменные типа boolean в VB имеют значение "ложь", если им не присвоены иные значения, поэтому включите в программу код, присваивающий функции значение "истина" по достижении успеха.

Функция OpenChair открывает набора записей ADO Recordset по известному ID объекта "стул", переданного функции, и заполняет экземпляр класса по результатам перемещения к первой записи набора Recordset. В листинге 1.10 приведен исходный код функции OpenChair. Так как ID объекта "стул" является уникальным в базе данных, то ввиду ограничений работы с данными безопаснее считать, что функция возвращает только одну строку данных, и, как правило, следует использовать именно первую строку. Recordset исследуется на наличие данных с помощью проверки BOF (начало файла) и EOF (конец файла) – они не должны равняться значению "истина". Если значение параметров BOF и EOF равно "истине", то в наборе Recordset записи отсутствуют. Выполнение команды MoveFirst в пустом наборе Recordset приведет к ошибке. Свойства EOF или BOF всегда проверяются перед прохождением по набору Recordset в одном из направлений при помощи команд MoveNext или MovePrevious.



'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'OpenChair ' Opens an existing record for a chair and 'populates the object with the values ' 'in: Chair ID to open 'out: returns true on success and false otherwise '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Public Function OpenChair(ID As String) As Boolean On Error GoTo Sub_Error_Handler Const ERROR_MESSAGE_INFO = "OpenChair"

Const COMMAND_PREFIX = "SELECT * FROM tblChair WHERE ([ID]='" Const COMMAND_SUFFIX = "')"

Dim sSQL As String Dim rs As ADODB.Recordset

'build the insert statement sSQL = COMMAND_PREFIX & ID & COMMAND_SUFFIX

'get Recordset Set rs = GetADORecordSet(sSQL)

'make certain we got a valid Recordset If rs Is Nothing Then Err.Raise 1001, ERROR_MESSAGE_INFO, _ "Failure Opening Chair ID = " & ID End If

'make certain that we got a Recordset 'with at least 1 value If rs.EOF And rs.BOF Then Err.Raise 1001, ERROR_MESSAGE_INFO, _ "Failure - record for Chair does not exist. ID = " & ID End If

rs.MoveFirst

'set new ID to local setting m_sID = rs(CHAIR_ID)

'set new color to local setting color = rs(CHAIR_COLOR)

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub_Exit_Done: 'return success value

OpenChair = True

On Error Resume Next 'destroy objects Set rs = Nothing Exit Function

Sub_Error_Handler: ProcessErr "Failure Opening Chair ID = " & ID

End Function

Листинг 1.10. Function OpenChair

Набор Recordset, полученный для OpenChair, создан другой вспомогательной ADO-функцией – GetADORecordSet. Как и ExecuteCommand, GetADORecordSet воспринимает выражение SQL как параметр и открывает набор Recordset из источников данных в локальном экземпляре m_Connection объекта Connection. Объект набора записей передается в вызывающую функцию. В листинге 1.11 приведен исходный код функции GetADORecordSet.

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'GetADORecordSet 'Sends SQL command to datasource and returns 'an ADO Recordset to the function consumer '



'in: vsSource - SQL string to execute 'out: returns true on success, false otherwise '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Private Function GetADORecordSet(ByVal vsSource As String) _ As ADODB.Recordset

On Error GoTo Sub_Error_Handler Const ERROR_MESSAGE_INFO = "GetADORecordSet"

Dim rsRequested As ADODB.Recordset Dim cmdRequested As ADODB.Command

'establish connection If m_Connection.State <> adStateOpen Then Err.Raise 1001, ERROR_MESSAGE_INFO, _ "Connection Object is not open. Database connect be opened." End If

'establish command Set cmdRequested = CreateObject("ADODB.Command") Set cmdRequested.ActiveConnection = m_Connection

'set up command object cmdRequested.CommandType = adCmdText cmdRequested.CommandText = vsSource

'Create instance of Recordset object Set rsRequested = cmdRequested.Execute

'return Recordset If Not rsRequested Is Nothing Then If rsRequested.State = adStateOpen Then Set GetADORecordSet = rsRequested Else 'rsRequested state is not open Err.Raise 1001, ERROR_MESSAGE_INFO, _ " Recordset state is not open " & vsSource End If Else 'rsRequested is nothing error Err.Raise 1001, ERROR_MESSAGE_INFO, _ " Recordset object is nothing " & vsSource End If

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub_Exit_Done: 'return value On Error Resume Next 'destroy objects Set rsRequested = Nothing Set cmdRequested = Nothing Exit Function

Sub_Error_Handler: ProcessErr " Failure obtaining Recordset."

End Function

Листинг 1.11. Function GetADORecordSet

Существует много возможностей по усовершенствованию функции GetADORecordSet. Одной из них является установка набора ADO Recordset как параметра функции, передаваемого в ByRef, и возврат значения "истина" или "ложь" в зависимости от результата извлечения набора Recordset. Программа расходует ресурсы на создание набора записей ADO Recordset только один раз, и функция сообщит вызывающей функции о правильности набора Recordset.Функции ExecuteCommand и GetADORecordSet можно объединить в одну.


Содержание раздела