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.  Использование при сохранении изменений и формирования полных текстов запросов, и параметрических запросов.


 

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

34537. Проблема гуманизма в произведениях А. Де Сент-Экзюпери. «Маленький принц» как сказка-притча 18.04 KB
  Маленький принц как сказкапритча. Маленький принц был написан в 1943 году и трагедия Европы во второй мировой войне воспоминания писателя о разгромленной оккупированной Франции накладывают свой отпечаток на произведение. То что Маленький принц сказка мы определяют по имеющимся в повести сказочным признакам: фантастическое путешествие героя сказочные персонажи Лис Змея Роза. Прообразом литературной сказки Маленький принц можно считать фольклорную волшебную сказку с бродячей фабулой: прекрасный принц изза несчастной любви...
34538. От Сюрреализма к соцреализму. Арагон и Элюар 18.91 KB
  Арагон и Элюар СЮРРЕАЛИЗМ Мировой центр Париж но среди участников движения были и немцы и чехи и американцы. Участники необычайно имениты: Арагон Ренуар Дали и т. Арагон поэт и романист которому принадлежит видное место во французской литературе социалистического реализма крупный общественный деятель. стала для Арагона первой школой жизни.
34539. Своеобразие мифотворчества Ф. Кафки 18.94 KB
  Странность Грегоранасекомого в том что он начинает превращаться и превращается не в насекомое а в Человека. Звучит абсурдно но мизансцена свидетельствует о том что Грегор трутень на нем паразитирует вся семья. Грегор Замза просыпаясь утром понимает кто он есть на самом деле и образ жука здесь служит символом очищения души ее возрождении и освобождении от гнета. Грегор человек в обличии насекомого; его родичи насекомые в человеческом облике.
34540. Теория эпического театра и Конфликт и его худ. воплощение в пьесах Брехта 17.5 KB
  Среди наиболее знаменитых пьес эмиграции Матушка Кураж и ее дети 1939. В условиях 30х годов Матушка Кураж звучала конечно как протест против демагогической пропаганды войны фашистами и адресовалась той части немецкого населения которая поддалась этой демагогии. Сущность эпического театра становится особенно ясной в связи с Матушкой Кураж . Поэтому в Матушке Кураж столь последовательный и выдержанный даже в мелких деталях подлинный лик жизни.
34541. Тема «потерянного поколения» в литературе 1 половины 20 в. (Э.М. Ремарк, Р. Олдингтон, Ф.С. Фицджеральд, Э. Хемингуэй и др.) 17.11 KB
  и Хемингуэя Прощай оружие. Все вы потерянное поколение эпиграф Хемингуэя затем стал лит. Они индивидуалисты и надеются как герои Хемингуэя лишь на себя на свою волю а если и способны на решительный общественный поступок то сепаратно заключая договор с войной и дезертируя. Хемингуэй рассказал о возвращении с войны сборник рассказов В наше время 1925 о сущности неприкаянной жизни фронтовиков и их подруг об одиночестве невест не дождавшихся возлюбленных Фиеста 1926 о горечи прозрения после первого ранения и утраты...
34542. Тема антифашистского сопротивления в творчестве А. Зегерс 15.34 KB
  Зегерс. Анна Зегерс 19001983 псевдоним. Роман Седьмой крест давно признан лучшим романом Зегерс. В Седьмом кресте наиболее отчетливо сказалось замечательное умение Анны Зегерс показывать людей в нерасторжимом единстве личного и общественного ставить острые политические вопросы времени обращаясь к частной будничной жизни широких слоев народа.
34543. Исторический роман 13.83 KB
  В пределах этой общей характеристики исторического романа нового типа диапазона переходов и разновидностей достаточно велик: от модернизации истории т. романа в котором исторически достоверны сюжет основные факты описание быта национальный и временный колорит но в конфликты и отношения героев внесены современные мотивировки и проблемы Безобразная герцогиня или Еврей Зюсс Л. романа представляющего собой в сущности исторически костюмированную современность романа намеков и иносказаний в котором в условноисторической оболочке...
34544. Роман воспитания в немецкой литературе 16.13 KB
  Bildungsromn тип романа получивший распространение в литературе немецкого Просвещения. Роман воспитания традиционная разновидность жанра романа в эволюции которой проступает одна из магистральных линий развития немецкой романистики на протяжении нескольких столетий. Уходя своими истоками в глубь времен в рыцарские повествования средневековья и плутовской роман барокко XVII века он получил законченную классическую форму в творчестве великих просветителей Германии К.
34545. Интеллектуальный роман Т. Манна 18.45 KB
  Манна Термин интеллектуальный роман был впервые предложен Томасом Манном. Манна или Г. Манна или Гессе существенно отличается от психологизма например у Дёблина. Манна признает перед собравшимися свою вину.