Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование лекции.doc
Скачиваний:
49
Добавлен:
12.11.2019
Размер:
5.53 Mб
Скачать

30.4. Подключение к sql-серверу

Давайте будем создавать алиас программным путем, не заставляя пользователя лазить в BDE Administrator. Алиасы создаются при помощи компонента Session. Удобнее всего выполнять создание алиаса, а также открытие баз и прочие подготовительные операции в момент создания модуля данных, а закрытие сессии – в момент завершения его работы. Поэтому будем писать обработчик события OnCreate модуля данных. Убедитесь, что вы создаете обработчик именно для модуля данных (в инспекторе объектов вверху должно быть написано DM : TDM).

В разделе описаний (перед словом IMPLEMENTATION) надо объявить константы, задающие имя вашего алиаса и название директории, где лежат базы. Удобнее всего размещать базы в директории с каким-то фиксированным именем (например, DATA), которая отходит от директории местонахождения exe-файла программы (Рис. 30 .124).

Рис. 30.124 Размещение файлов программы и БД.

Перед созданием алиаса надо проверить, не создан ли он уже (иначе возникнет ошибка). Проверку выполняет метод IsAlias объекта Session, а создание – метод AddStandardAlias. В результате имеем следующий код:

CONST My_Alias='DVD';

datapth='data';

var

dm: Tdm;

implementation

{$R *.dfm}

procedure Tdm.DataModuleCreate(Sender: TObject);

begin

WITH Session DO

BEGIN

// на всякий случай сначала закрываем

Active:=FALSE;

// директория хранения временных файлов

PrivateDir:=ExtractFilePath(PARAMSTR(0));

Active:=TRUE;

// если алиаса нет

IF NOT(IsAlias(My_Alias)) THEN

BEGIN

// будем его сохранять в BDE

ConfigMode:=cmPersistent;

// создаем новый алиас AddStandardAlias(My_Alias,ExtractFilePath(PARAMSTR(0))+

datapth,'PARADOX');

// сохраняем алиас в BDE

SaveConfigFile

END;

// открываем базу данных

DataBase.AliasName:=My_Alias;

DataBase.Connected:=TRUE;

// открываем таблицу dvd.db

WITH DVD DO

BEGIN

Prepare;

Open

END

END

END;

На событии OnDestroy модуля данных надо закрывать таблицы, базы и сессию. Делается это так:

procedure Tdm.DataModuleDestroy(Sender: TObject);

begin

WITH Database DO

// база открыта?

IF Connected THEN

BEGIN

// закрываем все запросы

CloseDataSets;

// закрываем базу

Connected:=FALSE

END;

// закрываем сессию, если она открыта

WITH Session DO

IF Active THEN

Close

end;

31.Программная обработка данных в архитектуре "клиент – сервер"

31.1. Программный доступ к полям бд

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

Если БД вообще не выводится на экран, компонент DataSource не нужен. Достаточно компонента Query. Научимся выбирать требуемую запись в БД и обращаться к отдельным полям.

Возможны два способа выполнения поиска, сортировки и пр. операций: на стороне клиента и на стороне сервера. В первом случае всю работу выполняет компьютер клиента, а сервер "знать не знает" про ваши поиски. Во втором случае на сервер просто направляется SQL-запрос на поиск (скажем, команда SELECT с условием WHERE) и собственно поиск осуществляется сервером.

Поиск записи по условию на стороне клиента выполняет метод Locate объекта Query. Вот его общий вид:

LOCATE(список_полей, массив_значений, [режимы])

В списке полей их имена разделяются символом ";". Пусть мы хотим найти первую запись в БД dvd.db, у которой в поле YEARF хранится значение 2003. Поместите на форму кнопку и в ее обработчике события OnClick напишите следующий код:

BEGIN

dm.DVD.Locate('YEARF','2003',[])

END;

Разумеется, искомое значение можно вводить как переменную. Например, можно запросить год с клавиатуры. Параметр "режим" представляет собой множество, в которое могут быть включены следующие константы:

loCaseInsensitive – поиск текста без учета регистра;

loPartialKey – поиск по части выражения. Если начало текста в поле БД совпадает с выражением, считается, что запись найдена.

Если режим поиска менять не нужно, все равно следует написать пустое множество – [].

Если надо выполнять поиск по нескольким полям, придется использовать один трюк. Давайте найдем все фильмы с субтитрами, выпущенные в 2002г. Команда поиска будет иметь вид:

dm.DVD.Locate('YEARF;SUBTITLES',VarArrayOf(['2003',TRUE]),[])

Функция VarArrayOf объединяет свои аргументы различного типа в псевдо-массив.

Метод Locate возвращает значение True или False в зависимости от того, найдена запись или нет:

IF NOT(dm.DVD.Locate('YEARF;SUBTITLES',

VarArrayOf(['2003',TRUE]),[])) THEN

MessageDlg('Не найдено',mtInformation,[mbOK],0);

Итак, нужная строчка найдена. Чтобы получить значение конкретного поля в текущей строке БД, можно воспользоваться методом FieldByName:

VAR s:STRING;

BEGIN

dm.DVD.Locate('YEARF','2003',[]);

s:=dm.DVD.FieldByName('TITLE_RUSSIAN').AsString

END;

В приведенном примере в переменную s записывается значение поля TITLE_RUSSIAN. Обратите внимание на конструкцию AsString. При использовании метода FieldByName необходимо явно указывать тип значения, извлекаемого из поля. Основные варианты таковы:

AsFloat – вещественное число;

AsInteger – целое число;

AsBoolean – логическое значение;

AsString – текстовая строка.

Занесение значения в поле выполняется несколько сложнее. Во-первых, у компонента Query свойство RequestLive должно быть установлено в True. Во-вторых, перед изменением поля нужно вызывать метод Edit, а после изменения – метод Post:

WITH dm.DVD DO

BEGIN

Edit;

FieldByName('TITLE_RUSSIAN').AsString:='Терминатор 2';

Post

END;

Между Edit и Post можно менять содержимое нескольких полей сразу.

Еще несколько полезных методов:

Append – добавляет новую записи в конец БД, делает ее текущей и переводит БД в режим редактирования.

Delete – удаляет текущую запись из базы.

EmptyTable – страшный метод. Удаляет все строки из БД.

Предположим, нам нужно подсчитать количество фильмов в БД, выпущенных в 2001г. Организуем цикл по всем записям:

USES …., DB;

VAR cnt:WORD; b:TBookMark;

BEGIN

CNT:=0;

WITH dm.DVD DO

BEGIN

DisableControls;

b:=GetBookMark;

First;

WHILE NOT(EOF) DO

BEGIN

IF FieldByName('YEARF').AsString='2001' THEN

INC(cnt);

Next

END;

GotoBookMark(b);

EnableControls

END;

В USES надо вручную добавить модуль DB. Метод DisableControls временно отключает БД от ее отображения на экране. Если этого не сделать, то при выполнении цикла курсор в DBGrid начнет "бегать", что не только странно выглядит, но и заметно тормозит работу. Самое главное – не забыть в конце включить отображение БД методом EnableControls.

Перед началом цикла в переменную b при помощи метода GetBookMark запоминается текущая запись. После окончания цикла метод GotoBookMark снова делает текущей. Запись хранится в переменной типа BookMark.

Методы для перемещения по записям БД следующие:

First – на первую запись;

Last – на последнюю запись;

Next – на следующую запись;

Prior – на предыдущую запись.

Свойство EOF возвращает логическое значение в зависимости от того, достигнута последняя запись в БД или нет.