Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование от Чертенка.ру Выпуск 11. Работа с Oracle в Delphi. Компонент TOraQuery. Часть 3.


Информационный Канал Subscribe.Ru

Доброго времени суток, уважаемые подписчики!

Сегодня я продолжу рассказ про компонент TOraQuery.

Как я уже упоминал в прошлых выпусках, TOraQuery может выполнять почти любую sql-команду Oracle. Наиболее часто Вы будете выполнять DML-команды (Data Manipulation Language - язык управления данными, обычно это insert/update/delete), поэтому мы и будем рассматривать их. DDL-команды (Data Definition Language - язык описания данных - create/alter/drop/grant/revoke) выполняются аналогично DML-командам.

Выполняему команду нужно также поместить в свойство SQL:

OraQuery1.SQL.Text := 'delete from clients where fam like :fam';
OraQuery1.Params[0].AsString := Edit1.Text + '%';
OraQuery1.Execute;

Как видите, все точно также как и в случае с select-командами. Но тут есть свои ньюансы. Как вы знаете, DML-команды выполняются в контектсе транзакций. ODAC позволяет управлять транзакциями как явно, так и не явно.

Если OraSession.AutoCommit = True и OraQuery.AutoCommit = True, то ODAC автоматически будет фиксировать (COMMIT) каждую DML-команду (при подключении к Ораклу и первом выполнении любой DML-команды сервер неявно стартует транзакцию, но закрывать транзакцию (COMMIT или ROLLBACK нужно явно)). Если хоть у одного компонента (OraSession или OraQuery) AutoCommit = False, то ODAC не будет закрывать транзакцию и это нужно делать самостоятельно, например так:

OraQuery1.SQL.Text := 'commit';
OraQuery1.Execute;

При явном управлении транзакциями нужно не только явно закрывать транзакцию, но и открывать ее. Для этого у OraSession есть соответствующие методы. Для удобства работы можно написать свои сервисные процедурки, например такие:

// подключение к серверу
function TdmCommon.ConnectDatabase(aServer, aUserName, aPassword: string;
  aUseNet: Boolean): Boolean;
begin
  Result := False;
  with OraSession do begin
    // устанавливаем опцию Net
    Options.Net := aUseNet;
    // сервер, к которому подключаемся
    Server := aServer;
    // имя пользователя
    UserName := aUserName;
    // пароль
    Password := aPassword;
    // отключаем автоматическое завершение транзакций.
    // проще отключить в одном месте, чем потом у каждого компонента
    AutoCommit := False;
    // отключаем показ диалога ввода пароля
    ConnectPrompt := False;
    // подключаемся к серверу
    Connect;
    // стартуем тарнзакцию
    StartTransaction;
  end;

  OraErrorHandler1.Active := True;
  Result := True;
end;

// Отключаемся от сервера
procedure TdmCommon.DisconnectDataBase;
begin
  with OraSession do
    // если мы подключены
    if Connected then begin
      и есть активная транзакция, то завершим ее
      if InTransaction then Commit;
      // отключаемся от сервера
      Disconnect;
    end;
end;

// Подтверждаем транзакцию
procedure TdmCommon.Commit;
begin
  with OraSession do
    // Если транзакция активна
    if InTransaction then begin
      // Фиксируем ее
      Commit;
      // Стартуем новую
      StartTransaction;
    end;
end;

// Откатываем транзакцию
procedure TdmCommon.Rollback;
begin
  with OraSession do
    // Если транзакция активна
    if InTransaction then begin
      // Откатываем
      Rollback;
      // Стартуем новую
      StartTransaction;
    end;
end;

Есть еще один момент, на котором хотелось бы заострить внимание. Если Вы работали с другими компонентами доступа, то знаете, что для для выполнения команд, которые возвращают результирующий набор данных, используется метод Open, а для всех остальных команд - ExecSQL. И как могли заметить - я упорно везде использую метод Execute. Это не ошибка! Это одно из преимуществ ODAC'а по сравнению с другими компонентами доступа к Ораклу! Вам теперь не нужно заботиться о том, какой метод использовать Open или ExecSQL (использование "не своего" метода для выполнения команды положительного результата не дает, наоборот, могут быть ошибки), а смело используйте универсальный метод Execute, остальное за Вас сделает ODAC.

Обратимся еще раз к нашему примеру в начале выпуска.В нем мы выполняли команду delete. Но у OraQuery есть свойство SQLDelete и Вы можете спросить, не логичнее ли было указать эту команду там, а не в свойстве SQL? А ответ таков. В свойстве SQL указывается команда, которая будет выполена методами Execute/Open/ExecSQL. А в свойствах SQLInsert/SQLDelete/SQLUpdate задаются соответствующие команды для модификации данных, выбираемые основным запросом SQL. Эти свойства будут рассмотрены далее.

Рассмотрим типичный сценарий разработки формы по вводу новых данных. На форме расположены контролы и при нажатии на кнопку типа "Сохранить"/"Ок"/"Отправить" можно выполнить примерно такой код:

begin
  with OraQuery1 do
  begin
    // такой запрос можно указать еще на этапе design-time
    SQL.Text := 'insert into table(field1, field2, ...) values(:1, :2, ...)';
    Params[0].AsString := Edit1.Text;
    Params[1].AsInteger := StrToInt(Edit2.Text);
    ...
    Execute;
  end;
end;

Это все будет работать, но сам код выглядит коряво и по-деревенски :)ODAC позволяет упростить этот процесс и свести написание ручного кода до минимума. Для начала в SQL пишем запрос вида select * from table where id=:id,
вместо * можно указать список необходимых полей. Запрос обязательно должен быть параметрическим и возвращать одну запись или ничего. Причем отбираться записи должны по primary key. Для ввода/отображения информации нужно использовать db-ware компоненты, например те, что расположены на вкладке Data Controls или любой другой сторонней библиотеки и связать их с нашим OraQuery посредством DataSource. Теперь в SQLInsert пишем нужную нам команду insert, а в SQLUpdate - соответственно команду update. Хочу обратить Ваше внимание, что в редакторе OraQuery Editor есть вкладка SQL Generator, где ODAC поможет вам сгенерировать валидные команды, которые Вы может подкорректировать под свои нужды.

Самую сложную часть мы уже сделали, причем часть работы за нас сделал ODAC, а было бы неплохо, чтобы и форма делалась сама :) (Шепну на ушко, что есть компонент XMLInspector, который простые формы ввода/редактирования данных может генерировать сам - вот она мечта программиста :)). Для ввода записи в качестве параметра нужно передать несуществующий ключ (напрмер -1)
OraQuery.ParamByName('id').AsFloat := - 1;
OraQuery.Open; // или OraQuery.Execute;
// и выполнить метод Append - добавить запись
OraQuery.Append;
Когда нужно отправить данные на сервер, то просто выполняем OraQuery1.Post;, ну и конечно не забываем про транзакции.

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

При выполнении метода Post ODAC выполнит нужную команду insert/update из сооответсвующего свойства SQLInsert/SQLUpdate. В прошлом выпуске я говорил, что имена параметрам можно давать любые, но в некоторых случаях Делфи предъявляет определенные требования к ним. Тут как раз один из этих случаев, когда имя параметра должно строго соответствовать имени поля. Также следует обратить внимание на то, как ODAC сгененировал секцию where команды update: WHERE ID = :OLD_ID. Имя параметра OLD_ID говорит о том, что нужно подставить не текущее значение поля, а его предыдущее, которое запоминается в специальном буфере объекта-поля (об объектах полях речь еще пойдет ниже). Хотя кому прийдет в голову менять primary key? :)

ODAC также автоматизирует работу с primary key. Достаточно указать имя поля primary key в KeyFields, в KeySequence указать имя последовательности, которая будет генерировать значения, а в SequenceMode указать режим генерации уникального значения:

  • smInsert - значение первичного ключа будет сгенерировано при выполнении методов Append/Insert и есть возможность его изменить.
  • smPost - значение первичного ключа будет сгенерировано в момент выполнения команды insert.

Однако хорошей практикой является установка первичных ключей в триггерах.

В следующем выпуске я рассмотрю объекты-поля, а также другие компоненты ODAC.

Ждем Ваших откликов на емайл 5781-author@subscribe.ru или subscr@chertenok.ru


Приглашаем авторов в рассылку!


С уважением,
координатор рассылки Алексей aka Gelios.

Наши координаты:

сайт - www.delphi.chertenok.ru
форум - www.forum.chertenok.ru
контактный email - 5781-author@subscribe.ru

Другие проекты:

www.travel.chertenok.ru - сайт о путешествиях!



Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: comp.soft.prog.allofdelphi
Архив рассылки
Отписаться Вебом Почтой
Вспомнить пароль

В избранное