Программирование баз данных в Delphi (Создаем модуль для сжатия и восстановления базы данных).
Многие читатели моих уроков заметили, что при работе с базой данных
Microsoft Access (формат mdb) очень быстро растет ее размер, хотя сама
база практически пустая. И мне на почту приходят вопросы, как сжать
базу.
На сегодняшнем уроке я расскажу, как программно сжать базу данных Microsoft Access 2003-2007.
Ну во первых операцию по сжатью базы можно выполнить в ручную в самой
программе Microsoft Access 2007. Для этого необходимо выполнить
действия, показанные на рисунке:
Но нас интересует программный путь. Для этого
запускаем наш проект и переходим на главную форму (form_general).
Дважды кликаем мышью на компоненте MainMenu1 и создаем пункт меню
«Сервис» и подпункт «Сжатие и восстановление базы»:
Затем дважды кликаем на пункте «Сжатие и восстановление базы» и пишем следующий код:
procedure TForm_general.N11Click(Sender: TObject);
Var path,db,db1:string;
begin
//закрываем формы
if (form_general.MDIChildCount)<>0 then
begin
ShowMessage('Закройте все формы и повторите операцию.');
exit;
end;
if MessageBox(Handle, 'Вы приступили к сжатию и восстановлению базы
данных. Продолжить? ', 'Внимание !!!', MB_YESNO)<> IDYES then
exit;
//извлекаем путь к базе, в нашем случае это папка с нашим приложением
path:=ExtractFilePath(Application.ExeName);
db:=path+'storage.mdb';
//закрываем соединение с базой
for i:= 0 to ADOConnection1.DataSetCount - 1 do
ADOConnection1.DataSets[i].Close;
ADOConnection1.Connected:=False;
//вызываем процедуру сжатия и восстановления базы
CompactDatabase_JRO(db,'','');
end;
Изобретать велосипед я не буду, а возьму готовый код приведенный ниже:
Для его работы добавим в Uses модуль ComObj;
uses ……ComObj;
В разделе type процедуру Procedure CompactDatabase_JRO(DatabaseName:
String; DestDatabaseName: String=''; Password:String=''), собственно
которая и будет сжимать базу.
type
…………………..
…………………..
Procedure CompactDatabase_JRO(DatabaseName: String; DestDatabaseName: String=''; Password:String='');
В разделе implementation добавим код самой процедуры:
{ **** UBPFD *********** by delphibase.endimus.com ****
>> Программное сжатие базы данных Access используя JRO (Jet Replication Objects)
Процедура позволяет сжать базу данных в формате Access,
используя JRO (Jet Replication Objects). Действие аналогичное
пункту меню в Access "Сервис -> Служебные программы ->
Сжать и восстановить базу данных".
Параметры:
* DatabaseName - путь к исходной (не сжатой) базе данных
* DestDatabaseName - путь к сжатой базе данных
(по умолчанию пустой - в этом случае исходная база заменяется сжатой)
* Password - пароль базы данных (по умолчанию пустой)
Зависимости: windows,SysUtils,ComObj,Dialogs (Dialogs можно исключить
используя MessageBox для вывода сообщения исключительной ситуации)
Автор: savva, savva@nm.ru, ICQ:126578975, Орел
Copyright: Сапронов Алексей (Savva)
Дата: 9 сентября 2002 г.
***************************************************** }
procedure TForm_general.CompactDatabase_JRO(DatabaseName: string; DestDatabaseName: string =
''; Password: string = '');
const
Provider = 'Provider=Microsoft.Jet.OLEDB.4.0;';
var
TempName: array[0..MAX_PATH] of Char; // имя временного файла
TempPath: string; // путь до него
Name: string;
Src, Dest: WideString;
V: Variant;
begin
try
Src := Provider + 'Data Source=' + DatabaseName;
if DestDatabaseName <> '' then
Name := DestDatabaseName
else
begin
// выходная база не указана - используем временный файл
// получаем путь для временного файла
TempPath := ExtractFilePath(DatabaseName);
if TempPath = '' then
TempPath := GetCurrentDir;
//получаем имя временного файла
GetTempFileName(PChar(TempPath), 'mdb', 0, TempName);
Name := StrPas(TempName);
end;
DeleteFile(PChar(Name)); // этого файла не должно существовать, удаляем его :))
Dest := Provider + 'Data Source=' + Name;
if Password <> '' then
begin
Src := Src + ';Jet OLEDB:Database Password=' + Password;
Dest := Dest + ';Jet OLEDB:Database Password=' + Password;
end;
V := CreateOleObject('jro.JetEngine');
try
V.CompactDatabase(Src, Dest); // сжимаем
finally
V := 0;
end;
if DestDatabaseName = '' then
begin // т.к. выходная база не указана
DeleteFile(PChar(DatabaseName)); //то удаляем не упакованную базу
// и переименовываем упакованную базу
if RenameFile(Name, DatabaseName) then
begin
ShowMessage('Процедура сжатию и восстановлению базы
данных успешно завершена. Сейчас программа будет закрыта.');
Application.Terminate;
end;
end;
except
// выдаем сообщение об исключительной ситуации
on E: Exception do
ShowMessage(e.message);
end;
end;
Сохраняем проект. Внимание, при запуске из Delphi данной процедуры будет выскакивать ошибка:
Поэтому прежде, чем запустить проект его необходимо скомпилировать, и закрыть Delphi, а только потом запускать приложение.
Сайт очень хороший, много полезной информации, особенно новичкам, только такой вопрос - предложение, можно создать например тему где будут выкладываться материалы по программированию, причем на всех языках, не только на Delphi, например о C и С++.
Уважаемый администратор, очень помогли ваши уроки, огромное Вам спасибо, но если можно было бы Вас попросить поподробнее расписать данный алгоритм(создания резервной копии или если где то можно найти почитать не подскажете статью или ссылку) премного благодарен
Перезапись – Если такой файл уже существует, то будет ли он перезаписан (true - не будет, false - будет). Пример: CopyFile('storage.mdb', '\copy\storage.mdb', false);
Начальный файл это наша база к которой мы указывали путь в adoconnection, а конечный это надо полностью указать адрес нового файла? то есть допустим в главном меню будет находится mainmenu там будет кнопочка и при нажатии на нее должен быть следующий обработчик событий: procedure TForm1.N18Click(Sender: TObject); begin CopyFile('storage.mdb','copystorage.mdb',false); end;
А что должно происходить? После этой операции должна создаваться копия с именем copystorage.mdb в папке с приложением. Вообще восстановление из копии можно сделать так: Создаем в папке с приложением папку "copy" далее делаем две кнопки. Первая создать резервную копию, а вторая восстановить из копии. И вешаем на них следующий код: Для первой кнопки: begin CopyFile('storage.mdb','copy\copystorage.mdb',false); end;
Для второй: var i:integer; begin //закрываем формы if (form_general.MDIChildCount)<>0 then begin ShowMessage('Закройте все формы и повторите операцию.'); exit; end;
// закрываем соединения for i:= 0 to ADOConnection1.DataSetCount - 1 do ADOConnection1.DataSets.Close;
ADOConnection1.Connected:=False;
//Копирование резервной копии CopyFile('copy\copystorage.mdb','storage.mdb',false); ShowMessage('Сейчас приложение будет закрыто. Запустите его заново'); Application.Terminate; end;
Это наиболее простой вариант. В идеале нужно использовать диалог сохранения, чтоб можно было задать имя резервной копии и диалог восстановления, чтоб можно было выбрать копию. Далее можно создать автоматический перезапуск программы или без перезапуска, но программно восстановить соединение с базой, т.к. при перезаписи файла оно потеряется и активировать подключение всех таблиц, но это не быстро. Чтобы автоматический перезапустить приложение можно перед Application.Terminate; добавить следующую строку: