Sinkopa Здравствуйте еще раз!
Есть надобность перевода базы данных из microsoft access в mysql каждодневно. (то есть работает программка автономно с своей локальной базой *.mdb, в конце дня надо дописать mysql ). Таблица в *.mdb и содиржимое таблицы довольно мнгого. Хотелось бы сделать одной нажатии на кнопку в программе DELPHI а не конверитровать импортировать внешнеми программами.
У кого Если можно примерчик кода или работающий образец.
Хотел сначала поругаться... Потом погуглил (ради интереса) и с удивлением ничего внятного по вашему вопросу не обнаружил...
Так что ладно, считайте я сегодня добрый...
Рассказываю по-шагам-по-шагам... может еще кому нибудь сгодится.
Нам понадобятся:
1. Последнюя стабильная версия ZeosDBO.
Качаем и устанавливаем.
Ссылка скрыта от гостей
2. Клиентская dll для связи с MySQL.
Напоминаю что MySQL теперь Oracle и (по ряду причин) связывать с ними не будем.
Вместо этого будем использовать клиента от MariaDB. Он на 99,9% совместим с MySQL (вплоть до имен файлов в наборе установки сервера).
99,9% потому что при работе с сервером MySQL (не MariaDB) баги таки встречаются, но связаны они (как практика показывает) с косяками серверной стороны.
Поэтому иногда версию клиентской dll приходится подбирать персонально под конкрентную версию MySQL сервера.
Как правило ( у кого как не знаю, но лично у меня так было) вариации с dll-ками от MariaDB дают лучший результат чем с (родными) dll-ками от MySQL.
Но Вы можете поэкспериментировать самостоятельно
Итак. Идем сюда:
Ссылка скрыта от гостей
Что качать зависит от версии MySQL сервера, с которым Вы собираетесь работать. Совместимости на странице прописаны.
Я бы лично сразу попробовал самую свежую версию, но Вы смотрите сами.
В любом случае, нам нужен архив сервера MariaDB (не инсталлер).
После скачивания и распаковки нам из него понадобится файл libmysql.dll находящийся в директории lib.
Собственно всё. Предполагается MySQL сервер установлен, работает и доступен для коннекта.
Приступаем к программированию.
1. Создаём новый Delphi-проект с одной формой.
2. В свойствах назначаем целевой каталог для компиляции (у меня подпапка bin в каталоге компиляции). Сохраняем, компилим.
3. Настраиваем соединение с базой MS-Access.
Для "ясности" я положил в каталог bin тестовый файл "CARS.mdb" (рядом с exe-шником программы). Будем к нему подключаться.
Подключаться придется через ADO, что как известно вещь довольно "интимная".
Поэтому рассказываю самый простой (на мой взгляд) способ.
По шагам.
3.1. Кидаем на форму контрол TZConnection и обзываем его ZADOConn.
3.2. В выпадающем списке свойства Protocol выбираем "ado". Сохраняем проект.
3.3. Жмем кнопку "..." в свойстве Database и выбирраем совместимого OLE DB провайдера.
Я лично выбрал "Microsoft.Jet.OLEDB.4.0", ну а Вы уж сами смотрите что Вам "роднее"...
3.4. В том же окошке жмем "Next >>" и на закладке "Connection" указываем имя mdb-файла к которому будем подключаться и Security (логин, пароль) если тебуется.
3.5. Жмем "Test Connection". Убеждаемся что соединение успешно устанавливается, жмем "ОK","ОK"...
Все все проделанные манипуляции на скриншоте
В итоге в поле свойства ZADOConn.Database получаем (автоматически сгенерированную) строку соединения следующего содержания:
'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\ADO2MYSQL\bin\CARS.mdb;Persist Security Info=False'
Но мы ее там не оставляем.
Вместо этого в коде заводим строковую константу
Код:
const
ADO_CONNECTION = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;Persist Security Info=False';
и в обработчике FormCreate пишем код
Код:
procedure TForm1.FormCreate(Sender: TObject);
var
MDBFileName: string;
begin
MDBFileName := ExtractFilePath(Application.ExeName)+ 'CARS.mdb';
ZADOConn.Database := Format(ADO_CONNECTION,[MDBFileName]);
end;
Надеюсь Вам не надо объяснять почему так, для чего нам константа и функция Format ?
Нет? Отлично, продолжаем.
Соединение с MS-Access базой мы настроили, теперь нам надо подключиться к таблице которую надо пересохранять в MySQL
4.1. Бросаем на форму
TZReadOnlyQuery (обзываем ZADOQuery)
TDataSource (DataSource1)
TDBGrid (DBGrid1)
и кнопку Button1.
4.2. В обработчике Button1Click пишем код
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
if ZADOQuery.Active then
ZADOQuery.Active := False;
if ZADOConn.Connected then begin
ZADOConn.Disconnect;
Exit;
end;
ZADOQuery.Connection := ZADOConn;
DataSource1.DataSet := ZADOQuery;
DBGrid1.DataSource := DataSource1;
ZADOQuery.SQL.Text := 'SELECT * FROM CARS'; // CARS - имя таблицы
ZADOConn.Connect;
ZADOQuery.Active := True;
end;
4.3. Сохраняем, компилим, запускаем, жмем кнопку Button1, убеждаемся что в гриде отображается содержание нашей таблицы CARS.
Итак мы успешно зацепились к базе MS-Access и достучались к таблице. Закроем приложение и продолжим.
Теперь нам надо получиль список полей таблицы, чтобы мы смогли сформировать SQL запрос для сохранения данных в MySQL.
5.1. Кидаем на форму компонент TMemo (Memo1) и в обработчике Button1Click (в конце) дописываем код
Код:
for i := 0 to ZADOQuery.FieldCount-1 do
Memo1.Lines.Add(ZADOQuery.Fields[i].FieldName);
5.1. Сохраняем, компилим, запускаем, жмем кнопку Button1, копируем из Мемо его содержание.
5.2. Объявлем строковую константу, которая будет SQL-шаблоном вставки данных в MySQL.
У меня получилось следующее
Код:
const
MYSQL_INSERT = 'INSERT INTO `cars` (ID,Brand,Type,CC,PK,Cyl,KW,Price,Country) VALUES (:ID,:Brand,:Type,:CC,:PK,:Cyl,:KW,:Price,:Country);';
Имена полей мы взяли из Мемо, подстановочные параметры для значений совпадают с именами полей и расположены в том же порядке.
Со стороной MS-Access мы закончили. Настраиваем сторону MySQL.
Предполагается что что на сервере MySQL существует база данных с именем `cars` и в ней есть таблица с именем `cars` и соответствующим набором полей.
6.1. Копируем клиентскую библиотеку libmysql.dll в каталог рядом с экзешником.
6.2. Бросаем на форму
TZConnection (обзываем ZMySQLConn)
TZReadOnlyQuery (ZMySQLQuery)
и кнопку Button2.
6.3. В обработчике FormCreate дописываем код
Код:
ZMySQLConn.Protocol := 'MariaDB-5';
ZMySQLConn.LibraryLocation := ExtractFilePath(Application.ExeName)+ 'libmysql.dll';
{ у меня MySQL сервер на локальной машине
на порту 3306
}
ZMySQLConn.HostName := 'localhost';
ZMySQLConn.Port := 3306;
ZMySQLConn.User := 'root';
ZMySQLConn.Database := 'cars';
6.4. В обработчике Button2Click пишем код для проверки соединения с базой MySQL и нашей таблицей
Код:
procedure TForm1.Button2Click(Sender: TObject);
var
i: Integer;
begin
if ZMySQLQuery.Active then
ZMySQLQuery.Active := False;
if ZMySQLConn.Connected then begin
ZMySQLConn.Disconnect;
Exit;
end;
ZMySQLQuery.Connection := ZMySQLConn;
DataSource1.DataSet := ZMySQLQuery;
DBGrid1.DataSource := DataSource1;
ZMySQLQuery.SQL.Text := 'SELECT * FROM `cars`;'; // cars - имя таблицы
ZMySQLConn.Connect;
ZMySQLQuery.Active := True;
end;
6.5. Сохраняем, компилим, запускаем, жмем кнопку Button2, убеждаемся что в гриде отображается (если там есть данные) содержание нашей таблицы CARS в базе MySQL.
Всё. Все настройки завершены.
7. Пишем код главной кнопки...
Код:
procedure TForm1.ButtonClick(Sender: TObject);
var
i: Integer;
F: TField;
P: TParam;
begin
ZADOQuery.Active := False;
ZMySQLQuery.Active := False;
ZADOConn.Disconnect;
ZMySQLConn.Disconnect;
// подключаесмся к базе MS-Access
ZADOQuery.Connection := ZADOConn;
ZADOQuery.SQL.Text := 'SELECT * FROM CARS'; // CARS - имя таблицы
ZADOConn.Connect;
ZADOQuery.Active := True;
// подключаесмся к базе MySQL
ZMySQLQuery.Connection := ZMySQLConn;
ZMySQLConn.Connect;
// переносим данные
if ZADOQuery.Active and (ZADOQuery.RecordCount > 0)
and ZMySQLConn.Connected then begin
ZMySQLQuery.SQL.Text := MYSQL_INSERT; // SQL запрос вставки INSERT INTO...
ZMySQLQuery.Prepare; // разбор параметров
// переходим режим на "ручной" транзакции
ZMySQLConn.AutoCommit := False;
ZMySQLConn.TransactIsolationLevel := tiReadCommitted; // добавить в uses ZDbcIntfs
// поехали...
ZADOQuery.First; // переход к первой mdb записи
while not ZADOQuery.Eof do begin
// заносим значения полей mdb в параменты SQL запроса вставки
for i := 0 to ZADOQuery.FieldCount-1 do begin
F := ZADOQuery.Fields[i]; // поле mdb таблицы
P := ZMySQLQuery.ParamByName(F.FieldName); // одноименный параметр MySQL запроса
P.DataType := F.DataType;
P.Value := F.Value;
end;
ZMySQLQuery.ExecSQL; // выполнение запроса вставки в таблицу MySQL
ZADOQuery.Next; // переход к следующей mdb записи
end;
ZMySQLConn.Commit; // завершение транзакции
// возвращаем соединение в исходное состояние
ZMySQLConn.TransactIsolationLevel := tiNone; // добавить в uses ZDbcIntfs
ZMySQLConn.AutoCommit := True;
end;
// отключаемся
ZMySQLConn.Disconnect;
ZADOQuery.Active := False;
ZMySQLConn.Disconnect;
end;
8. Сохраняем, компилируем, запускаем и жмем "Главную кнопку".
Чтобы убедиться что все скопировалось как надо жмем кнопки Button2,Button2 и Button1. Сравниваем данные в гриде.
Компоненты DataSource1, DBGrid1, Memo1 и кнопки Button1, Button2 нам больше не нужны.
Удаляем с формы за ненадобностью (и тестовый код обработчиков Button1Click и Button2Click).
Суперприложение для переноса mdb -> MySQL с использованием ZeosDBO готово.
У меня всё. Архив с исходниками в аттаче поста.