Категории
Самые читаемые
Лучшие книги » Компьютеры и Интернет » Программирование » Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil - А Ковязин

Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil - А Ковязин

Читать онлайн Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil - А Ковязин

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 28 29 30 31 32 33 34 35 36 ... 112
Перейти на страницу:

Рис. 2.5. Вызов редактора TIBTransaction

В появившемся диалоге вы сможете указать нужный уровень изоляции, а заодно и увидеть сразу, какими константами он задается (рис. 2.6.).

Рис 2.6. Редактор TIBTransaction

Для большинства случаев рекомендуется использовать режим Read Committed, который позволит запросам в одной транзакции "видеть" изменения, сделанные и подтвержденные в контексте других транзакций.

TIBTransaction ссылается на компонент базы данных при помощи свойства DetaultDatabase. Если также указать свойство DefaultTransaction у TIBDatabase, то в дальнейшем любые компоненты (TIBDataSet, TffiSQL и т. д.), которые ссылаются на TIBDatabase, будут автоматически "подхватывать" и указанную транзакцию.

Теперь рассмотрим свойства AllowAutoStart и AutoStopAction. Как вам уже известно, любой запрос к базе данных должен выполняться в контексте транзакции. То есть, прежде чем выполнить даже простейший запрос вида SELECT * FROM TABLE 1, необходимо предварительно запустить транзакцию при помощи вызова IBTransaction.StartTransaction.

Такой "ручной" вызов не всегда удобен. Более того, каждый раз совершенно определенно известно: если мы хотим выполнить запрос, то мы должны запустить транзакцию. Чтобы избежать лишнего кода, связанного с запуском транзакций, можно установить значение свойства AllowAutoStart равным True. В этом случае если мы попробуем, например, открыть TIBDataSet, то он сам автоматически запустит соответствующую транзакцию.

Аналогичный смысл имеет свойство AutoStop Action. Когда мы закрываем все запросы, выполнявшиеся в контексте автоматически запущенной транзакции, то TIBTransaction выполняет действие, указанное в AutoStopAction. Например, автоматически подтверждает всю транзакцию при помощи метода Commit, если свойство AutoStopAction равно saCommit. Таким образом, разработчику предоставляется возможность указать, как компоненты должны автоматически взаимодействовать друг с другом!

Выполнение запросов при помощи TIBDataSet

В данной главе сознательно не рассматривается работа с TIBTable или TIBQuery, так как авторы книги не считают их использование целесообразным. Если вы все же желаете использовать эти компоненты (например, для облегчения миграции приложения с BDE), то для из>че- ния их функций можно обратиться к документации по аналогичным BDE-компонентам, а также к документации по IBX.

Итак, поместите на форму следующие компоненты:

IBDataSetl: TIBDataSet;

DataSourcel: TdataSource

DBGridl: TDBGrid

Необходимо указать свойства Database и Transaction у IBDataSetl, задать DataSourcel.DataSet равным IBDataSetl, а также указать DBGridl.DataSource равным DataSourcel.

Теперь необходимо указать тот запрос, который мы хотим выполнить, в свойстве SelectSQL у IBDataSetl (рис. 2.7).

Рис 2.7. Редактор свойства SelectSQL

Теперь мы можем открыть запрос прямо в design-time, задав свойство Active в True. Результат наших действий приведен на рис. 2.8.

Рис 2.8. Открытие запроса в IBDataSet1

Чтобы получить то же самое во время выполнения программы, напишите следующий обработчик события OnFormCreate у основной формы приложения'

procedure TForml.FormCreate(Sender: TObject);

begin

IBDatabasel.Open;

IBDataSetl.Open;

end;

He забудьте закрыть подключение к базе данных перед сохранением проекта, иначе попытка IBDatabase I .Open вызовет ошибку. Вы также можете написать этот код иначе: IBDatabasel Connected := True; IBDataSetl.Active := True. Он не вызовет сообщения об ошибке, если IBDatabasel и IBDataSetl были активны в design-time.

Редактируемые запросы

Редактирование данных при помощи визуальных компонентов

Если вы уже запустили пример, представленный выше, и попробовали исправить хотя бы одну запись в таблице, то наверняка получили сообщение, что сделать это невозможно. Причины этого сообщения очевидны, поскольку компонент IBDataSetl имеет только свойство SelectSQL. Это свойство содержит запрос на выборку записей, его выполнение позволяет получить список тех записей из таблицы EMPLOYEE с сервера, которые удовлетворяют условию в WHERE.

А для того чтобы, к примеру, исправить какую-либо запись, необходимо выполнить команду UPDATE. В общем случае выполнение этой команды может вообще не зависеть от нашего запроса в SelectSQL.

Но поскольку TIBDataSet был спроектирован в первую очередь для того, чтобы использоваться совместно со стандартными визуальными компонентами, то он предоставляет нам средства для автоматического выполнения тех модифицирующих запросов, которые необходимы для изменения данных, полученных при помощи SelectSQL. Чтобы окончательно не запутаться, давайте подробнее рассмотрим этот вопрос.

Итак, мы открыли запрос в SelectSQL. Как видно из рисунка, первая полученная запись содержит имя сотрудника Robert. Предположим, мы хотим исправить это имя на John.

В момент изменения произойдет следующее: в локальном буфере IBDataSetl у текущей записи значение поля FIRST_NAME будет изменено с Robert на John. В базе данных данное изменение пока никак не отражается. Чтобы произвести фактическое изменение данных на сервере, необходимо выполнить соответствующий запрос с UPDATE. Этот запрос необходимо заранее указать у компонента IBDataSetl в свойстве ModifySQL:

UPDATE EMPLOYEE

SET

EMP_NO = :EMP_NO,

FIRST_NAME = :FIRST_NAME,

LAST_NAME = :LAST_NAME,

PHONE_EXT = :PHONE_EXT,

HIRE_DATE = :HIRE_DATE,

DEPT__NO = :DEPT_NO,

JOB_CODE = :JOB_CODE,

JOB_GRADE = :JOB_GRADE,

JOB_COUNTRY = :JOB_COUNTRY,

SALARY = :SALARY WHERE

EMP_NO = :OLD_EMP_NO

Как видно из примера, вместо реальных значений в этом запросе указаны параметры, названия которых совпадают с названием реальных полей. Таким образом, когда пользователь изменит значения полей конкретной записи, ю jtBDataSetl сам задаст значения всех параметров, взяв их из соответствующих |полей. В частности, значение параметра :FIRST_NAME будет равно John. Запрос шз ModifySQL выполнится, и только после этого изменения, сделанные пользователем, окажутся в базе данных.

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

Обратите внимание на префикс OLD_ в названии параметра :OLD_EMP_NO. Данный префикс означает, что IBDataSet должен подставить в параметр значение поля до изменения пользователем.

Итак, если мы сформируем все модифицирующие запросы, то наш IBDataSet позволит пользователям редактировать данные, т. е. мы фактически получим запрос, который разработчики на Delphi/C-H-Buildei обычно называют "живым"(live query).

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

SELECT

EMP_NO,

FIRST_NAME,

LAST_NAME,

PHONE_EXT,

HIRE_DATE,

DEPTMTO,

JOB_CODE,

JOB_GRADE,

JOB_COUNTRY,

SALARY,

FULL_NAME

FROM EMPLOYEE

WHERE

EMP_NO = :EMP_NO

Смысл данного запроса становится очевидным, если допустить существование в базе данных триггеров для таблицы EMPLOYEE, которые модифицируют значения полей. Поскольку изменения происходят в самой базе данных сразу после вставки или после изменения записей, то без повторного перечитывания записи (т. е. без Select только что вставленной или измененной записи), мы не узнаем о тех изменениях, которые были сделаны в триггерах. Можно, конечно, вообще переоткрыть весь запрос, заданный в SelectSQL.

Именно такой механизм и реализуется в BDE, когда мы вынуждены целиком переоткрывать все запросы. В IBX без этого легко можно обойтись, используя RefieshSQL, значительно сэкономив при этом сетевой трафик и снизив нагрузку на сервер, поскольку получение всего лишь одной измененной записи гораздо более эффективно, чем переоткрытие запроса целиком.

IBX предоставляет нам возможность быстро сгенерировать необходимые модифицирующие запросы при помощи редактора IBDataSet (рис 2.9.)

Выбрав из списка Table Name нашу таблицу и нажав кнопку Get Table Fields мы сформируем списки Key Fields и Update Fields. В списке Key Fields нужно выделить те поля, которые будут формировать условие WHERE в наших запросах. Очевидно, что это должны быть поля, которые определяют первичный ключ у таблицы. Если такой ключ существует для выбранной таблицы, то вы можете просто нажать на кнопку Select Primary Keys, чтобы автоматически выделить нужные поля.

Рис 2.9. Генератор модифицирующих запросов

В списке Update Fields необходимо выделить те поля, которые потом пользователь сможет редактировать. На рисунке видно, что поле FULL_NAME не включено в список, поскольку это CALCULATED-поле и его значение нельзя менять

К сожалению, надо самому точно знать, какие поля необходимо исключать из модифицирующих запросов поскольку компоненты не дадут ни одной подсказки. Даже при подготовке данного раздела пришлось потратив впустую некоторое время, чтобы понять, почему IBDataSetl никак не "хотел" становиться модифицируемым. Только выяснив, что поле FULL_NAME является вычислимым, стало понятно, почему возникает ошибка IBDataSetl пытался выполнить команду Prepare для каждого из запросов и сервер каждый раз сообщал, что не может изменить read-only-поле! Хочется отметить, что этой проблемы нет в генераторе запросов, реализованном в FIBPlus.

1 ... 28 29 30 31 32 33 34 35 36 ... 112
Перейти на страницу:
На этой странице вы можете бесплатно скачать Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil - А Ковязин торрент бесплатно.
Комментарии