Программирование баз данных в Delphi

Автор работы: Пользователь скрыл имя, 26 Января 2013 в 14:13, лекция

Краткое описание

Программирование баз данных - очень большой и серьезный раздел самого что ни на есть практического программирования. На предыдущем курсе "Введение в программирование на Delphi" мы лишь коснулись этой темы, затронули даже не верхушку айсберга под названием Базы Данных, а только его макушку. Между тем, многие программисты большую часть своего времени тратят именно на проектирование баз данных и разработку приложений, работающих с ними. Это неудивительно - в настоящее время каждая государственная организация, каждая фирма или крупная корпорация имеют рабочие места с к

Вложенные файлы: 1 файл

Программирование баз данных в делфи.doc

— 2.17 Мб (Скачать файл)

Подготовим диалоговые компоненты. Выделите их и присвойте свойству Filter обоих компонентов строку

Таблицы dBase|*.dbf

Таким образом, мы указали, что диалоги  будут работать только с таблицами  типа dBase. Кроме того, у обоих диалогов измените свойство DefaultExt, указав там:

dbf

Это свойство указывает расширение файла по умолчанию, если пользователь не назначит расширения сам.

В свойстве DataSet компонента DataSource1 выберите таблицу Table1. В свойстве DataSource сетки DBGrid1 и навигатора DBNavigator1 выберите имеющийся DataSource1. Теперь при открытии таблицы она будет отображаться в сетке, а навигатор позволит управлять ей.

Теперь сложнее - настраиваем компонент Table1. Табличный компонент TTable имеет одно важное свойство TableType, с которым раньше нам не приходилось сталкиваться; компонент TADOTable такого свойства не имеет. Это свойство указывает на тип используемой или создаваемой таблицы. Свойство может иметь следующие значения:

Таблица 9.1 . Значения свойства TableType компонента TTable

Значение 

Описание 

ttASCI

Таблица содержится в формате обычного текстового файла. Строки и поля разделяются специальными символами - разделителями. Имя файла таблицы имеет расширение *.TXT

ttDBase

Таблица содержится в формате dBase, файл по умолчанию имеет расширение *.DBF

ttDefault

Компонент определяет тип таблицы по расширению имени  файла таблицы. При создании таблицы, если не указано расширение имени файла, принимается тип Paradox.

ttFoxPro

Таблица содержится в формате FoxPro, файл по умолчанию также имеет расширение *.DBF

ttParadox

Таблица содержится в формате Paradox, файл по умолчанию имеет расширение *.DB


Если выбран тип таблицы (не ttDefault), то будет использован этот тип вне зависимости от расширения указанного имени файла таблицы.

В свойстве TableType компонента Table1 выберите значение ttDBase, то есть, таблица будет работать только с типом dBase. Далее дважды щелкните по компоненту, открыв редактор полей. Нам нужно будет добавить запланированные ранее поля. Щелкните по редактору правой кнопкой, выберите команду New Field (Новое поле). В поле Name впишите имя поля, например, FCeloe. В поле Type выберите тип поля Integer. В поле Size нужно указывать размер поля, но это справедливо только для текстовых полей и полей типов Memo или BLOB. Убедитесь, что переключатель Field Type установлен на Data, это создаст пустое поле указанного типа. Нажав кнопку "ОК" добавьте объект-поле в редактор полей.

Таким же образом создайте еще несколько  разнотипных полей. Каждому полю присвойте уникальное имя (ведь в  таблице не может быть двух полей  с одинаковым именем!). Важно, чтобы  вы добавляли только те типы полей, которые поддерживаются выбранным типом таблиц, в нашем случае это dBase. При добавлении типа Memo укажите размер от 1 до 255, например, 50. В этом случае в файле таблицы *.dbf будет сохранен текст поля в 50 символов. Текст, который не уместится в этот размер, будет сохранен в файле Memo с таким же именем, но с расширением *.dbt.

Делать табличный компонент  активным на этапе проектирования не нужно. Итак, не имея базы данных, не имея физической таблицы, мы заранее установили тип таблицы и нужные нам поля. Как вы, наверное, догадываетесь, мы также имеем возможность сразу настроить нужные нам форматы для каждого поля, изменяя такие его свойства, как DisplayFormat, EditMask, DisplayLabel и др.

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

  //если пользователь  не выбрал таблицу, выходим:

  if not SaveDialog1.Execute then Exit;

  //закроем таблицу, если вдруг уже есть открытая:

  Table1.Close;

  //вначале устанавливаем  адрес базы данных:

  Table1.DatabaseName := ExtractFilePath(SaveDialog1.FileName);

  //теперь устанавливаем имя таблицы:

  Table1.TableName := SaveDialog1.FileName;

  //физически создаем таблицу:

  Table1.CreateTable;

  //и открываем ее:

  Table1.Open;

  //запишем имя открытой  таблицы:

  fMain.Caption := 'Таблица - '+ Table1.TableName;

Комментарии к каждой строке достаточно подробны, чтобы вы самостоятельно разобрались с кодом. Метод CreateTable() компонента-таблицы создает файл таблицы, и дополнительные файлы (Memo, индексные), если они нужны. В свойстве DatabaseName табличного компонента вы можете установить любой необходимый вам адрес, мы использовали папку, выбранную диалогом SaveDialog.

Для кнопки "Открыть таблицу" код будет почти таким же:

  //если пользователь  не выбрал таблицу, выходим:

  if not OpenDialog1.Execute then Exit;

  //закроем таблицу, если вдруг уже есть открытая:

  Table1.Close;

  //вначале устанавливаем  адрес базы данных:

  Table1.DatabaseName := ExtractFilePath(OpenDialog1.FileName);

  //теперь устанавливаем имя таблицы:

  Table1.TableName := OpenDialog1.FileName;

  //открываем таблицу:

  Table1.Open;

  //запишем имя открытой  таблицы:

  fMain.Caption := 'Таблица - '+ Table1.TableName;

Откомпилировав программу и поработав с ней, вы обнаружите, что можете создавать и открывать сколь угодно много таблиц программно. При этом на каждую таблицу создается по два файла (если вы используете поле Memo). Попробуйте таким же образом создать таблицу типа Paradox.

BDE. Таблица с ключом и индексами.

В задачу данного раздела входит создание таблицы Paradox с различными типами полей, с первичным ключом и индексами по текстовому полю как в возрастающем, так и в убывающем порядке. Редактор полей компонента TTable при этом вызывать не нужно, добавлять поля мы тоже будем программно. В целях экономии места проектирование формы приложения не описывается - это несложная задача. Вы можете создать главную форму такой же, как в предыдущем примере, только кнопка там будет одна. При нажатии на эту кнопку мы должны открыть таблицу, если она существует, или создать и открыть новую таблицу. Располагаться таблица должна в той же папке, откуда запущено приложение. Файл с таблицей Paradox назовем Proba.db, файлы с Memo и индексные файлы сгенерируются автоматически, также с именем Proba, но с разными расширениями.

На форму добавьте компонент TTable с вкладки BDE, свойству Name которого присвойте значение TMy (вместо Table1), а свойству TableType значение ttParadox. Если у вас в приложении есть сетка DBGrid и (или) навигатор DBNavigator, то добавьте также компонент DataSource, который необходимо подключить к таблице TMy, а сетку и навигатор - подключить к DataSource. Здесь следует иметь в виду одну деталь: описание методов создания полей и индексов хранится в модуле DBTables, который подключается к вашей форме сразу, как вы установите компонент TTable. Если же вы используете модуль данных, и устанавливаете табличный компонент там, то и создавать таблицу нужно тоже в этом модуле, а в главной форме лишь вызывать процедуру создания таблицы. Но в нашем простом примере модуля данных нет, модуль DBTables указан в разделе Uses главной формы, и никаких проблем возникнуть не должно.

Код нажатия на кнопку выглядит так:

{Если таблицы нет - создаем  и открываем ее, если есть-

 просто открываем}

procedure TfMain.Button1Click(Sender: TObject);

begin

  //если таблица есть - открываем ее и выходим:

  if FileExists(ExtractFilePath(Application.ExeName) + 'Proba.db')

    then begin

    TMy.DatabaseName := ExtractFilePath(Application.ExeName);

    TMy.TableName := 'Proba.db';

    TMy.Open;

    Exit;

  end; //if

 

  {Если дошли до этого  кода, значит таблицы еще нет.

   Указываем данные  таблицы:}

  TMy.DatabaseName := ExtractFilePath(Application.ExeName);

  TMy.TableType := ttParadox;

  TMy.TableName := 'Proba';

 

  {Создаем поля:}

  with TMy.FieldDefs do begin

    //вначале очистим:

    Clear;

    //добавляем поле-счетчик   типа автоинкремент:

    with AddFieldDef do begin

        Name := 'Key';

        DataType := ftAutoInc;

        Required := True;

    end; //with

    //добавляем текстовое поле:

    with AddFieldDef do begin

        Name := 'Name';

        DataType := ftString;

        Size := 30;

    end; //with

    //добавляем поле дата:

    with AddFieldDef do begin

        Name := 'Date';

        DataType := ftDate;

    end; //with

    //добавляем логическое поле:

    with AddFieldDef do begin

        Name := 'MyLog';

        DataType := ftBoolean;

    end; //with

    //добавляем целое поле:

    with AddFieldDef do begin

        Name := 'MyInt';

        DataType := ftInteger;

    end; //with

    //добавляем вещественное поле:

    with AddFieldDef do begin

        Name := 'MyReal';

        DataType := ftFloat;

    end; //with

    //добавляем денежное поле:

    with AddFieldDef do begin

        Name := 'MyCurr';

        DataType := ftCurrency;

    end; //with

    //добавляем поле Memo:

    with AddFieldDef do begin

        Name := 'MyMemo';

        DataType := ftMemo;

        Size := 20;

    end; //with

  end; //with

 

  {Создаем ключ и индексы:}

  with TMy.IndexDefs do begin

    Clear;

    //делаем первичный ключ:

    with AddIndexDef do begin

      Name := '';

      Fields := 'Key';

      Options := [ixPrimary];

    end;

    //делаем индекс  в возрастающем порядке:

    with AddIndexDef do begin

      Name := 'NameIndxASC';

      Fields := 'Name';

      Options := [ixCaseInsensitive];

    end;

    //делаем индекс в убывающем порядке:

    with AddIndexDef do begin

      Name := 'NameIndxDESC';

      Fields := 'Name';

      Options := [ixCaseInsensitive, ixDescending];

    end;

  end; //with

 

  //создаем таблицу:

  TMy.CreateTable;

  //и открываем ее:

  TMy.Open;

end;

 

Разберем приведенный код. Первый блок выполняет проверку на наличие  таблицы. Таблица ищется в папке, откуда была запущена программа. Если таблица найдена, то компоненту TMy присваиваются свойства DatabaseName (папка, где располагается таблица) и TableName (имя таблицы). В нашем случае таблица называется Proba.db, но вы можете усложнить программу, используя диалог OpenDialog, как в прошлом примере. В этом случае пользователь сможет выбрать не только имя таблицы, но и ее расположение. Далее таблица открывается, а оператор Exit досрочно завершает выполнение процедуры.

Если выполнение процедуры продолжается, значит, таблица не была найдена. В  этом случае мы заполняем свойства компонента-таблицы DatabaseName, TableType и TableName необходимыми значениями.

Далее начинаем добавлять поля. Чтобы  уменьшить код, мы используем оператор with. Напомню, что этот оператор создает блок кода, который относится к указанному в with объекту. Так, вместо

with TMy.FieldDefs do begin

  Clear;

можно было бы написать

TMy.FieldDefs.Clear;

В случае одиночного оператора это  допустимо, но в случае множественных  команд ссылаться в каждой строчке  на объект будет утомительно. Свойство FieldDefs таблицы содержит описание полей этого набора данных. Таким образом, мы начинаем с того, что очищаем это описание.

Далее у нас идет метод AddFieldDef, предназначенный для добавления поля в описание. Опять же, чтобы не ссылаться каждый раз на этот метод, мы используем вложенный оператор with для каждого добавляемого поля.

В простейшем случае в блоке добавления нового поля требуется указать только два свойства объекта-поля: Name (имя поля) и DataType (тип поля). С именем все понятно, а что касается типа поля, то он определяется свойством DataType класса TField. Чтобы получить подробную справку по возможным типам полей, установите курсор в редакторе кода на слове DataType и нажмите <Ctrl+F1>, чтобы вызвать контекстную справку. В списке тем выберите ту тему, которая относится к классу TField, а в открывшейся справке щелкните по ссылке TFieldType (относится к Delphi 7, хотя возможно, имеется и в предыдущих версиях). Откроется страница с подробным описанием типов полей. При использовании этого метода следует сверяться, имеется ли выбранный тип поля в таблицах используемого формата.

Помимо этих двух свойств, при необходимости  могут использоваться и другие:

Required - Логическое свойство. Если равно True, то значения поля должны быть уникальными (не могут повторяться). В нашем примере такое свойство имеется у поля, которое мы будем использовать как первичный ключ.

Size - Указывает размер поля. Используется в основном, со строковыми и Memo- полями.

После того, как в список полей  были добавлены все необходимые  поля, начинаем создание первичного ключа и индексов. Если за список полей отвечает свойство FieldDefs таблицы, то за список индексов отвечает свойство IndexDefs, а за добавление нового индекса - метод AddIndexDef. По аналогии с полями, используем оператор with для уменьшения кода. Для каждого индекса требуется указать по три свойства: Name (имя индекса), Fields (имя поля, по которому строится индекс) и Options (параметры индекса). Параметры индекса указаны в таблице 9.2:

Таблица 9.2. Параметры типов индекса

Тип

Описание 

ixPrimary

Первичный индекс (ключ). Не применяется с таблицами  типа dBase.

ixUnique

Уникальный  индекс. Значения этого поля не могут  повторяться.

ixDescending

Индекс в  убывающем (обратном) порядке.

ixExpression

Ключевой индекс для таблиц dBase.

ixCaseInsensitive

Индекс, нечувствительный к регистру букв.

ixNonMaintained

Этот тип  используется редко. Он подразумевает, что при редактировании пользователем значения индексируемого поля, индексный файл автоматически не обновляется.


Как видно из примера, свойству Options можно присвоить не один параметр, а список параметров:

Options := [ixCaseInsensitive, ixDescending];

Далее все просто: указав необходимые поля и индексы, методом CreateTable формируются физические файлы таблицы. Сама таблица имеет расширение *.db, файл с полем Memo - *.mb, остальные файлы содержат созданные индексы.

Для сортировки данных используем индексы. У нас их два -'NameIndxASC' (в возрастающем порядке) и 'NameIndxDESC' (в убывающем порядке). Чтобы сортировать данные, например, в убывающем порядке, нужно указать имя соответствующего индекса в свойстве IndexName компонента-таблицы:

TMy.IndexName := 'NameIndxDESC';

Если же мы хотим снять сортировку, то достаточно просто присвоить этому свойству пустую строку:

TMy.IndexName := '';

Описываемый выше пример взят из справочника Delphi и приведен с небольшими доработками. Пример описывает практически все аспекты создания таблицы; по аналогии вы сможете создавать таблицы любой сложности.

ADO. Создание простой таблицы  посредством запроса SQL

Создание таблицы выполняется SQL-запросом CREATE TABLE. Тут есть одно но: дело в том, что существует два типа SQL-запросов. Запрос, который возвращает набор данных и начинается оператором SELECT, выполняется простым открытием компонента-запроса. При этом выполняется запрос, который содержится в свойстве SQL компонента.

Информация о работе Программирование баз данных в Delphi