35142

Программная реализация выборки и модификации данных в базе данных Interbase

Практическая работа

Информатика, кибернетика и программирование

При этом сохранение результатов редактирования выполняется путем вызова рассмотренной ранее функции pplyUpdtes класса TBDEDtSet и всех его потомков например компонента Query содержимое выборки которого редактируется и кэшируется которая выполняет отправку в БД закэшированных на клиентской стороне изменений. Пример реализации функции обработки события OnUpdteRecord: void __fstcll TDtModule1::Query1UpdteRecordTDtSet DtSet TUpdteKind UpdteKind TUpdtection Updtection { switch UpdteKind { cse ukModify: brek; cse ukInsert:...

Русский

2013-09-09

56.5 KB

2 чел.

Практическая работа №6

Программная реализация выборки и модификации данных в базе данных Interbase

Borland C++Builder 6 предоставляет несколько наборов компонентов для реализации доступа к БД. Рассмотрим базовый набор BDE.

Набор компонентов BDE размещен на закладке BDE палитры компонентов.

Для установления соединения с БД используется объект класса TDatabase. Он должен быть размещен в контейнере DataModule. При этом первоначально в BDE Administrator или в SQL Explorer должен быть создан псевдоним (alias) БД. Компонент TDatabase может подключиться по имени БД, указанному путем, только к БД форматов dBase и Paradox. Для прочих БД (в частности, Interbase) необходимо указывать псевдоним, предварительно созданный в административных средствах BDE.

Создание псевдонима выполняется в BDE Administrator или в SQL Explorer в дереве БД, представленном на закладке Databases. Для создания псевдонима используется функция “New…”, вызываемая из контекстного меню корня дерева Databases. При создании выбирается имя драйвера БД – “INTRBASE”. Для созданного псевдонима настраивается путь и имя файла в свойстве “SERVER NAME”, а также имя административного пользователя “SYSDBA” в свойстве “USER NAME”.

После того, как псевдоним создан, может быть организовано подключение к БД в разрабатываемом проекте. Для этого у компонента Database настраивается свойство AliasName, а также вводится произвольное имя DatabaseName. При попытке установки в значение “true” свойства Connected будет выдан диалог ввода имени пользователя и пароля. Вводятся имя и пароль администратора “SYSDBA” – “masterkey”. Ввод имени и пароля будет выполняться каждый раз при подключении БД, в частности, каждый раз при запуске программы. Если есть необходимость скрыть ввод имени и пароля от пользователя, то они могут быть введены как параметры в свойстве Params объекта Database:

USER NAME=SYSDBA

PASSWORD=masterkey

Обратите внимание, что, несмотря на установку параметров, запрос пароля производится будет. Для того, чтобы вообще исключить вывод окна запроса, сбрасывается значение свойства LoginPrompt объекта Database.

Для доступа к объектам БД используются изученные в предыдущих работах компоненты TTable и TQuery. В свойстве DatabaseName компонента Table вводится имя БД, которое было указано в свойстве DatabaseName компонента Database. В результате, если компонент Database был предварительно подключен к БД, в свойстве TableName компонента Table предоставляются на выбор имена таблиц, входящих в эту базу данных. При корректной настройке можно выбрать имя таблицы и установить свойство Active объекта Table. Если свойство успешно установлено, значит, таблица открыта. Теперь можно известными методами организовать подключение компонентов DataSource и DBGrid для визуализации таблицы на форме. Не забудьте включить в модуль формы при помощи директивы #include заголовочный файл модуля данных. Тогда настройка подключения невизуальных компонентов к визуальным будет производится естественно.

Аналогично к компоненту Database подключается компонент Query.

Самостоятельно проанализируйте возможности редактирования таблицы, выведенной в компонент DBGrid при помощи невизуального компонента Table. Проанализируйте возможности редактирования таблицы, являющейся подчиненной.

Результаты селектирующего запроса, выполняемого при помощи компонента Query, могут быть выведены в DBGrid. При этом в общем случае результаты запроса являются нередактируемыми. Выборку можно сделать редактируемой путем установки свойства RequestLive компонента Query. Причем установка этого свойства означает лишь попытку сделать выборку редактируемой, которая может и завершиться неудачей. При этом генерируется исключение, которое может быть перехвачено, а проверка того, является ли выборка редактируемой осуществляется при помощи свойства CanModify. Результат указанной попытки зависит от того, насколько данная функциональность поддерживается используемым SQL-сервером. В большинстве случаев редактируемыми можно сделать только запросы, возвращающие данные из одной таблицы.

Сделать редактируемыми выборки из нескольких таблиц можно путем использования кэшированных изменений (установка флага CachedUpdates) и события OnUpdateRecord. При этом Query «считает», что разработчик описал необходимую алгоритмику обработки результатов пользовательского редактирования. В результате выборка становится редактируемой.

При этом сохранение результатов редактирования выполняется путем вызова рассмотренной ранее функции ApplyUpdates класса TBDEDataSet и всех его потомков (например, компонента Query, содержимое выборки которого редактируется и кэшируется), которая выполняет отправку в БД закэшированных на клиентской стороне изменений. Функция ApplyUpdates может быть вызвана по завершению работы с программой или по директивному указателю пользователя. В процессе выполнения ApplyUpdates вызывается обработчик OnUpdateRecord. Пример реализации функции обработки события OnUpdateRecord:

void __fastcall TDataModule1::Query1UpdateRecord(TDataSet *DataSet,

 TUpdateKind UpdateKind, TUpdateAction &UpdateAction)

{

switch (UpdateKind)

{

 case ukModify: break;

 case ukInsert:

  ExecQuery->SQL->Text = "INSERT INTO people "

   + "(id, name1, name2, name3) VALUES ("

   + IntToStr(DataSet->FieldByName("ID")->AsInteger) + ", \'"

   + DataSet->FieldByName("NAME1")->AsString + "\', \'"

   + DataSet->FieldByName("NAME2")->AsString + "\', \'"

   + DataSet->FieldByName("NAME3")->AsString + "\');";

  ExecQuery->ExecSQL();

  ExecQuery->SQL->Text = "INSERT INTO job_dict "

   + "(id, name) VALUES ("

   +IntToStr(DataSet->FieldByName("ID_2")->AsInteger)+", \'"

   + DataSet->FieldByName("NAME")->AsString + "\');";

  ExecQuery->ExecSQL();

  ExecQuery->SQL->Text = "INSERT INTO jobs "

   + "(id, p_id, j_id, bdate, edate) VALUES ("

   + DataSet->FieldByName("ID_1")->AsString + ", "

   + DataSet->FieldByName("P_ID")->AsString + ", "

   + DataSet->FieldByName("J_ID")->AsString + ", \'"

   + DataSet->FieldByName("BDATE")->AsDateTime + "\', \'"

   + DataSet->FieldByName("EDATE")->AsDateTime + "\')";

  ExecQuery->ExecSQL();

  break;

 case ukDelete: break;

};

}

//---------------------------------------------------------------------------

DataSet – это тот набор данных, для которого вызывается функция применения обновлений. UpdateKind – тип обновления (модификация, вставка, удаление). Параметр UpdateAction должен устанавливаться в значение uaApplied в случае корректного завершения работы обработчика. В противном случае он останется в значении uaFail, которое передает обработчику вызывающая функция.

В данном примере выводимый набор данных представляет собой выборку из трех соединенных таблиц, в результате чего изменение каждой записи набора данных должно отражаться в трех таблицах. В данном случае используется компонент ExecQuery класса TQuery, выполняющий чисто экзекутивные функции, т.е. предназначенный для запуска запросов на обновление, а не на выборку. Трижды запускается его метод ExecSQL для выполнения обновления в трех таблицах. При этом в запросы типа INSERT подставляются значения из текущей записи набора данных DataSet, адресуемые именами полей при помощи функции FieldByName. Можно значения полей не «подхватывать на лету», используя имена полей, а заранее в конструкторе создать набор объектов, связанных с полями набора данных (Fields Editor… в контекстном меню компонента типа «набор данных», в частности, TTable, TQuery и т.д.). При этом можно будет обращаться к этим полям, которые всегда будут содержать значения полей актуальной записи и, кроме того, будут типизированы, т.е. можно будет сразу получать их значение (свойство Value), а не обращаться к свойствам типа AsXXX, как в приведенном примере.

В приведенном примере, что очевидно, не хватает обработки операций модификации записи и удаления записи. Кроме того, отсутствует указанная установка параметра UpdateAction. В зависимости от специфики предметной области этот фрагмент также следовало бы дополнить логикой проверки отсутствия в таблицах записей с соответствующими наименованиями. Генерацию уникального значения идентификатора производят на уровне БД, создавая для этого триггер и генератор.

А вот как можно реализовать ту же обработку вставки записи в набор данных при помощи параметризованных запросов:

ExecQuery->ParamByName("PID")->Value =

DataSet->FieldByName("ID")->AsInteger;

ExecQuery->ParamByName("PNAME1")->Value =

DataSet->FieldByName("NAME1")->AsString;

ExecQuery->ParamByName("PNAME2")->Value =

DataSet->FieldByName("NAME2")->AsString;

ExecQuery->ParamByName("PNAME3")->Value =

DataSet->FieldByName("NAME3")->AsString;

ExecQuery->ExecSQL();

ExecQuery1->ParamByName("PID")->Value =

DataSet->FieldByName("ID_2")->AsInteger;

ExecQuery1->ParamByName("PNAME")->Value =

DataSet->FieldByName("NAME")->AsString;

ExecQuery1->ExecSQL();

ExecQuery2->ParamByName("PID")->Value =

DataSet->FieldByName("ID_1")->AsInteger;

ExecQuery2->ParamByName("PPID")->Value =

DataSet->FieldByName("P_ID")->AsInteger;

ExecQuery2->ParamByName("PJID")->Value =

DataSet->FieldByName("J_ID")->AsInteger;

ExecQuery2->ParamByName("PBDATE")->Value =

DataSet->FieldByName("BDATE")->AsDateTime;

ExecQuery2->ParamByName("PEDATE")->Value =

DataSet->FieldByName("EDATE")->AsDateTime;

ExecQuery2->Prepare();

ExecQuery2->ExecSQL();

Те же самые значения, которые в предыдущем примере использовались для формирования текстов SQL-запросов сейчас просто передаются компоненту класса TQuery в виде параметров, адресуемых по имени. При этом вместо одного компонента TQuery, как в предыдущем примере, используется три отдельных компонента с заготовленными текстами параметризованных SQL-запросов. Например, запрос, содержащийся в свойстве SQL объекта ExecQuery. Представляет собой следующую строку:

INSERT INTO people (id, name1, name2, name3)

VALUES (:PID, :PNAME1, :PNAME2, :PNAME3);

Отсюда видно, что параметры в тексте параметризованного запроса обозначаются двоеточиями. После ввода такого текста запроса параметры становятся доступны в свойстве Params объекта TQuery. Там, в частности, может быть настроен тип каждого параметра.

В качестве завершающего этапа разработки отключите все имеющиеся подключения к БД в конструкторе (в среде разработки Borland C++Builder) и реализуйте установку подключений при создании модуля данных (событие OnCreate объекта DataModule).

В результате выполнения работы должна быть получена программа, работающая с БД Interbase и включающая в себя:

  1.  Отображение в таблице (DBGrid) результатов выполнения сложного запроса, выполняющего соединение таблиц.
  2.  Сохранение в БД изменений, внесенных в выборку, путем использования события OnUpdateRecord. Должно поддерживаться сохранение всех трех видов изменений: удаление, модификация, вставка. Должна быть реализована поддержка необходимой логики, например, удаление записи из главной таблицы только в случае отсутствия подчиненных записей.
  3.  Использование при сохранении изменений и формирования полных текстов запросов, и параметрических запросов.


 

А также другие работы, которые могут Вас заинтересовать

14568. Операторы управления программой в Java 194.5 KB
  Лабораторная работа Java3 Тема: Операторы управления программой в Java. Цель изучить основные операторы Javaпрограмм. Операторы Как вы знаете любой алгоритм предназначенный для выполнения на компьютере можно разработать используя только линейные вычисления р
14569. Введение в OpenGL. Рисование простейших геометрических объектов. Работа с OpenGL при помощи GLUT 78.5 KB
  Лабораторная Работа № 1 Введение в OpenGL. Рисование простейших геометрических объектов. Работа с OpenGL при помощи GLUT. 1. Что такое GLUT OpenGL является мультиплатформенной библиотекой т.е. программы написанные с помощью OpenGL можно легко переносить на различные операц...
14570. Примитивы OpenGl 90 KB
  Лабораторная работа №2 Примитивы OpenGl Точки линии треугольники четырехугольники многоугольники простые объекты из которых состоят любые сложные фигуры. В предыдущей главе мы рисовали сферу конус и тор. OpenGL непосредственно не поддерживает функций для с...
14571. Используя принципы ООП реализовать программу для вычисления площади фигур 16.74 KB
  Отчет по лабораторной работе №2 по дисциплине: Объектноориентированное программирование Постановка задачи Используя принципы ООП реализовать программу для вычисления площади следующих фигур: Эллипс Прямоугольник Треугольник. В программе необх
14572. Ввод и взаимодействие с пользователем и анимация Взаимодействие с пользователем в OpenGL 50.5 KB
  Лабораторная работа №3 Ввод и взаимодействие с пользователем и анимация Взаимодействие с пользователем в OpenGL Функции библиотеки GLUT реализуют так называемый событийноуправляемый механизм. Это означает что есть некоторый внутренний цикл который запускается
14573. Модель разноцветного куба. Способы получения плоских проекций трехмерных объектов. Задание положения и ориентации камеры 81.5 KB
  Лабораторная работа №4 Модель разноцветного куба. Способы получения плоских проекций трехмерных объектов. Задание положения и ориентации камеры. 1.Рисование трехмерного куба. Куб следует рассматривать как шесть многоугольников которые определяют его грани. Мас
14574. Работа с изображением. Наложение текстуры 67 KB
  Лабораторная работа №5 Работа с изображением. Наложение текстуры. 1.Работа с изображением Существует множество графических форматов bmp pcx gif jpeg и прочие. OpenGL напрямую не поддерживает не один из них. В OpenGL нет функций чтения/записи графических файлов. Но подде
14575. Использование источников света в OpenGL и свойств материала 70 KB
  Лабораторная работа №6 Использование источников света в OpenGL и свойств материала. 1.Описание источников света в OpenGL. В системе OpenGl поддерживаются источники света четырех типов: фонового освещения ambient lighting точечные источники point sources прожекторы spotlights удален
14576. Кривые и поверхности в OpenGL 75 KB
  Лабораторная работа № 7 Кривые и поверхности в OpenGL Кривые Безье Кривая Безье задается векторной функцией одной переменной Cu = [ Xu Yu Zu] Где u изменяется в некоторой области например [0.0 1.0]. Фрагмент поверхности Безье задается векторной фу