Нужен Пример По Работе Онлайн С Mysql Базами Данных

  • Автор темы basenowse
  • Дата начала
P

plugovich

Здравствуйте sinkopa!
Спасибо за очень подробное описание роботы с ZEOS. Так как в интернете очень мало подробной информации – Ваши статьи, да еще с тестовым примером, помогли во многом разобраться!
Вот только нужен Ваш совет!
При попытке запросить и вывести список пользователей из таблицы mysql.user столкнулся с крякозяблами имен пользователей, как на своей тренировочной программе, так и на Вашей тестовой! Собственно, вопрос: в какую сторону копать чтоб выводилось все нормально?

Р.S. Скрин Вашей программы:
 
M

-master-

копать в сторону SET NAMES, или юникод
 
S

SKS

sinkopa спасибо за столь развёрнутый урок по подключению к БД и внесению изменений!
Подскажите как реализовать проверку пользователя из таблицы с именем user?
Авторизация проходит у меня так:
Код:
 ZConnection1.HostName := 'srh.webhost1.ru';
ZConnection1.Port := 3306;
ZConnection1.Protocol := 'mysql';
ZConnection1.User := edit1.Text;
ZConnection1.Password := edit2.Text;
Это я авторизуюсь под администратором, а как пройти авторизацию взяв к примеру логин: vasia пароль: pupkin из таблицы users?
Префикс таблицы is1nm_ , не могу реализовать авторизацию в таблице is8nm_users в которой хранятся зарегистрированные пользователи.
Заранее благодарю!
 
S

sinkopa

sinkopa спасибо за столь развёрнутый урок по подключению к БД и внесению изменений!
Подскажите как реализовать проверку пользователя из таблицы с именем user?
Авторизация проходит у меня так:
Код:
 ZConnection1.HostName := 'srh.webhost1.ru';
ZConnection1.Port := 3306;
ZConnection1.Protocol := 'mysql';
ZConnection1.User := edit1.Text;
ZConnection1.Password := edit2.Text;
Это я авторизуюсь под администратором, а как пройти авторизацию взяв к примеру логин: vasia пароль: pupkin из таблицы users?
Префикс таблицы is1nm_ , не могу реализовать авторизацию в таблице is8nm_users в которой хранятся зарегистрированные пользователи.
Заранее благодарю!
;) Не понял вопрос.
Чтобы "взять" какие нибудь данные из таблицы users необходимо вначале аторизоваться с правами получения данных из этой таблицы.
Обычно это бывает суперадмин либо спецадмин заведующий юзерами. Это вопервых.

Во вторых - в "правильной" базе пароли юзеров хранятся в зашифрованном виде.
Даже если Вы "возъмете" таки пароль из таблицы users, то там скорее всего будет зашифрованная строка и чтобы получить из нее "pupkin" потребуется еще знать ключ шифорвания... :)

Но вообще это у Вас вопрос скорее по администрированию MySQL и к Delphi не относится.
В соответствующем разделе форума Вам подробнее объяснят как и что там (в MySQL) с юзерами паролями и авторизацией.
 
S

SKS

Я думал сделать так:
Человек регистрируется на сайте, его данные помещаются в БД, программа авторизуется в БД под администратором, пользователю остаётся лишь ввести свои данные которые он указал при регистрации.
То есть я хотел чтобы моё приложение использовало авторизацию с привязкой к БД, чтобы пользователю небыло необходимости входить на сайт и получать необходимую информацию.
Попробую поискать еще варианты для выхода из ситуации, всё-равно спасибо!
 
M

-master-

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

SKS

это простой запрос, есть такой или нет, где тут проблему нашли?
как его реализовать?
То есть можно не подключаясь к БД сделать запрос? Если есть возможность можете выложить код запроса?
 
M

-master-

select * from ... where ....
примерно вот так
 
S

SKS

типа как скушать яблоко, если его нет?
Я понял. Придется реализовать чтобы программа сама авторизовалась в БД под администратором, и лишь потом пользователь мог делать запрос. Но существует вероятность декодирования программы и выдирание логина и пароля администратора БД.
Или стоит реализовать через php чтобы выводилась страница авторизации.
 
N

nick1976

sinkopa, здравствуйте. Я воспользовался Вашим примером и попытался прочитать таблицу, но получил такой вот лог:

015-02-11 14:39:00 cat: Connect, proto: mysql-5, msg: CONNECT TO "" AS USER "root"
2015-02-11 14:39:01 cat: Execute, proto: mysql-5, msg: use vtp;

2015-02-11 14:39:01 cat: Execute, proto: mysql-5, msg: show tables;

2015-02-11 14:39:01 cat: Execute, proto: mysql-5, msg: select * from opl;

2015-02-11 14:39:01 cat: Execute, proto: mysql-5, msg: SHOW TABLES FROM LIKE 'opl', errcode: 1064, error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIKE 'opl'' at line 1

Исходный материал:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ZIBEventAlerter, ZSequence, ZSqlMonitor,
ZSqlProcessor, ZSqlMetadata, ZConnection, ZStoredProcedure, ZSqlUpdate,
ZAbstractTable, ZDataset, ZAbstractDataset, DB, ZAbstractRODataset,
DBTables, ZDbcLogging, ExtCtrls, DBCtrls, Grids, DBGrids;

type
TForm1 = class(TForm)
zzonly: TZReadOnlyQuery;
zqry1: TZQuery;
ztbl1: TZTable;
con1: TZConnection;
btn1: TButton;
lst1: TListBox;
lst2: TListBox;
zsqlmntr1: TZSQLMonitor;
mmo1: TMemo;
db1: TDatabase;
ds1: TDataSource;
dbgrd1: TDBGrid;
dbnvgr1: TDBNavigator;
mmo2: TMemo;
btn2: TButton;
procedure btn1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure zsqlmntr1LogTrace(Sender: TObject; Event: TZLoggingEvent);
procedure btn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
F: bool;
CreateResult: Boolean;

implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);

begin
{ZQuery1.Connection := ZConnection1;
DataSource1.DataSet := ZQuery1;
DBGrid1.DataSource := DataSource1;
DBNavigator1.DataSource := DataSource1;}
if con1.Connected then
begin
con1.Disconnect;
MessageBox(Handle, отключение',
PChar(Application.Title), MB_OK + MB_ICONINFORMATION + MB_TOPMOST);
Exit;
end;

{ инициализация }
con1.HostName := 'localhost';
con1.Port := 3306;
con1.Protocol := 'mysql';
con1.User := 'root';
con1.Password := 'password';

{ подключение }
try
con1.Connect;
MessageBox(Handle,'подключено',
PChar(Application.Title), MB_OK + MB_ICONINFORMATION + MB_TOPMOST);
ztbl1.Connection := con1;

except
MessageBox(Handle, 'ошибка подключения',
PChar(Application.Title), MB_OK + MB_ICONSTOP + MB_TOPMOST);

end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
con1.Disconnect;
end;

procedure TForm1.zsqlmntr1LogTrace(Sender: TObject; Event: TZLoggingEvent);
begin
mmo1.Lines.Add(Event.AsString);
end;

procedure TForm1.btn2Click(Sender: TObject);
begin

zqry1.SQL.Text:='use vtp;';
zqry1.ExecSQL;

zqry1.SQL.Text := 'show tables;';
zqry1.Active := True;

zqry1.SQL.Text:=' select * from opl;';
zqry1.Active:=true;
end;

end

Подскажите, пожалуйста, где я не прав.
 
S

sinkopa

sinkopa, здравствуйте. Я воспользовался Вашим примером и попытался прочитать таблицу, но получил такой вот лог:
015-02-11 14:39:00 cat: Connect, proto: mysql-5, msg: CONNECT TO "" AS USER "root"
2015-02-11 14:39:01 cat: Execute, proto: mysql-5, msg: use vtp;
2015-02-11 14:39:01 cat: Execute, proto: mysql-5, msg: show tables;
2015-02-11 14:39:01 cat: Execute, proto: mysql-5, msg: select * from opl;
2015-02-11 14:39:01 cat: Execute, proto: mysql-5, msg: SHOW TABLES FROM LIKE 'opl', errcode: 1064, error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIKE 'opl'' at line 1
Подскажите, пожалуйста, где я не прав.
Ну... я не экстрасенс вообще то... Но если принять за аксиому что в базе vtp у Вас есть таблица с именем opl то
Код:
procedure TForm1.btn2Click(Sender: TObject);
begin
zqry1.SQL.Text:='use vtp;';
zqry1.ExecSQL;

zqry1.SQL.Text := 'show tables;';
zqry1.Active := True; // <------ Вот до сюда Вы вроде как "правы"... а дальше нет :)

// 1. сначала необходимо закрыть датасет
zqry1.Active := False;
// 2. потом только делать новый SQL
zqry1.SQL.Text:=' select * from opl;';

// 3. теперь можно открыть датасет с новым запросом
zqry1.Active:=true;
end;
А еще (на вскидку)
1. Насколько я помню, у show tables; в разных версиях MySQL были отличия в синктасисе...
советую уточнить:
2. В некоторых ситуациях "use vtp;" может не сработать (например если раньше был открыт датасет с запросом в базу указанную в свойстве con1.Database)
Лучше выполнять прямые запросы (с указанием имени базы) типа 'SELECT * FROM `vtp`.`opl`;'
3. Для того чтобы лучше понимать почему вдруг SQL запросах "чтото не работает" я проверяю работу этих запросов с помощью сторонних утилит.

PS
В любом случае всегда необходимо проверять совместимость версий используемой клиентской DLL с целевым движком базы данных.
Прошу обратить внимание, что со времени моего первого поста в данной теме "много воды утекло"... :(
За это время как минимум MySQL стал Oracle... и разработчики ZEOSDBO "ушли" от MySQL в сторону MariaDB в след за (собственно разработчиками MySQL)...
 
N

nick1976

Спасибо большое!
Я использовал запрос 'SELECT * FROM `vtp`.`opl`;' и получил адекватный красивый ответ. Вопрос решен!
 
S

Stoun

Как получить список пользователей на сервере MySQL
На форме:
Код:
type
TForm1 = class(TForm)
ZConnection1: TZConnection;
ZReadOnlyQuery1: TZReadOnlyQuery;
ListBox1: TListBox;
btnShowUsers: TButton;
procedure btnShowUsersClick(Sender: TObject);
private
public
end;
Код:
Код:
procedure TForm1.btnShowUsersClick(Sender: TObject);
var
s: string;
begin
if not ZConnection1.Connected then
ZConnection1.Connect;
 
ListBox1.Clear;
 
try
with ZReadOnlyQuery1 do
begin
Close;
SQL.Text := 'SELECT User, Host FROM mysql.user;';
Open;
First;
while not Eof do
begin
ListBox1.Items.Add(Fields[0].AsString+'@'+Fields[1].AsString); //userName@userHost
Next;
end;
end;
finally
ZReadOnlyQuery1.Close;
end;
end;

Как отобразить (на форме) привилегии пользователя на сервере MySQL
(1) Кладем на форму TCheckListBox (CheckListBox1) и заполняем его Items следующими элементами (по типам привилегий):
+
+

(2) Функция приведения привилегии к имени поля результирующего запроса:
Код:
function Cap2Priv(s: string): string;
begin
Result := '';
if (s = 'SELECT') then Result := 'Select_priv'
else if (s = 'INSERT') then Result := 'Insert_priv'
else if (s = 'UPDATE') then Result := 'Update_priv'
else if (s = 'DELETE') then Result := 'Delete_priv'
else if (s = 'CREATE') then Result := 'Create_priv'
else if (s = 'DROP') then Result := 'Drop_priv'
else if (s = 'RELOAD') then Result := 'Reload_priv'
else if (s = 'SHUTDOWN') then Result := 'Shutdown_priv'
else if (s = 'PROCESS') then Result := 'Process_priv'
else if (s = 'FILE') then Result := 'File_priv'
else if (s = 'GRANT') then Result := 'Grant_priv'
else if (s = 'REFERENCES') then Result := 'References_priv'
else if (s = 'INDEX') then Result := 'Index_priv'
else if (s = 'ALTER') then Result := 'Alter_priv'
else if (s = 'SHOW DATABASES') then Result := 'Show_db_priv'
else if (s = 'SUPER') then Result := 'Super_priv'
else if (s = 'CREATE TEMPORARY TABLES') then Result := 'Create_tmp_table_priv'
else if (s = 'LOCK TABLES') then Result := 'Lock_tables_priv'
else if (s = 'EXECUTE') then Result := 'Execute_priv'
else if (s = 'REPLICATION SLAVE') then Result := 'Repl_slave_priv'
else if (s = 'REPLICATION CLIENT') then Result := 'Repl_client_priv'
else if (s = 'CREATE VIEW') then Result := 'Create_view_priv'
else if (s = 'SHOW VIEW') then Result := 'Show_view_priv'
else if (s = 'CREATE ROUTINE') then Result := 'Create_routine_priv'
else if (s = 'ALTER ROUTINE') then Result := 'Alter_routine_priv'
else if (s = 'CREATE USER') then Result := 'Create_user_priv'
else if (s = 'EVENT') then Result := 'Event_priv'
else if (s = 'TRIGGER') then Result := 'Trigger_priv'
else if (s = 'CREATE TABLESPACE') then Result := 'Create_tablespace_priv';
end;
(3) Процедура отображения привилегий пользователя:
Код:
procedure TForm1.ShowPrivileges(const User, Host: string);
var
F: TField;
i: Integer;
begin
with ZReadOnlyQuery1 do
begin
Close;
SQL.Text := 'SELECT * FROM mysql.user WHERE ( User='''+ User +''' AND Host='''+Host+''' );';
Open;
First;
for i := 0 to CheckListBox1.Count-1 do
begin
CheckListBox1.Checked[i] := False;
F := FieldByName(Cap2Priv(CheckListBox1.Items[i]));
if (F <> nil) then
CheckListBox1.Checked[i] := F.AsBoolean;
end;
Close;
end;
end;
(4) Использование :)
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
UserName: string;
HostName: string;
begin
UserName := 'delphi';
HostName := 'localhost';
 
if not ZConnection1.Connected then
ZConnection1.Connect;
 
ShowPrivileges(UserName,HostName);
end;

при получении списка пользователя, в Вашем примере, в TListView создается список User, Host с не читаемыми символами, далее появляются ошибки, что это? не та кодировка? как это исправить?
 
S

sinkopa

... список User, Host с не читаемыми символами... что это? не та кодировка?
Тут, мой ответ утвердительный :)
... далее появляются ошибки ... как это исправить?

Хм... видимо обратиться к экстрасенсу... во всяком случае при такой постановке Вашего вопроса... :)
Операционная система? 32бит? х64?
Версия Delphi? Ansi? Unicode?
Версия ZeosDBO? старая (с поддержкой MySQL)? или уже новая (под MariaDB)?
Версия MySQL/MariaDB сервера? В какой кодировке хранятся строки на сервере? Какая кодировка по умолчанию назначается для клиентских соединений?
Версия клиентской dll которую Вы используете с ZConnection? Какой протокол в свойствах (mysql? mysql-5? mariaDB-5)?
Как инициализированы у ZConnection следующие свойства:
ControlsCodePage
AutoEncodeStrings
ClientCodepage
?
Подозреваю, Вы скажете что-то типа: "Я делал всё как у Вас написано..."
В этом случае мой ответ будет следующий: Обратите внимание на дату моего первого поста в этой теме... :)
В те времена MySQL еще не был Oracle и поддерживался разработчиками ZeosDBO. Да и сами разработчики MySQL не стали разработчиками MariaDB. И клиентские MySQL/MariaDB библиотеки были ансишные и собственной сборки ZeosGroup (сейчас необходимо брать клиента из поставки инсталлера сервера). И Delphi был под номером 7. И про WIN8 никто слыхом не слыхал... :)

Короче.
Вам в обязательном порядке необходимо посетить следующие ссылки:





Скачать, установить, настроить.
Если после этого если еще останутся вопросы - welcome!
 
  • Нравится
Реакции: vital
M

mrtg

Sinkopa Здравствуйте еще раз!
Заранее прошу прошение если я повторяюсь с вопросом или написал на другой теме.

Delphi,
Есть надобность перевода базы данных из microsoft access в mysql каждодневно. (то есть работает программка автономно с своей локальной базой *.mdb, в конце дня надо дописать mysql ). Таблица в *.mdb и содиржимое таблицы довольно мнгого. Хотелось бы сделать одной нажатии на кнопку в программе DELPHI а не конверитровать импортировать внешнеми программами.
У кого Если можно примерчик кода или работающий образец.

Заранее спс за внимание!
 
S

sinkopa

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"...

Все все проделанные манипуляции на скриншоте

ado1.png


В итоге в поле свойства 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 готово.
У меня всё. Архив с исходниками в аттаче поста.
 

Вложения

  • ADO2MYSQL.rar
    691,1 КБ · Просмотры: 280
Последнее редактирование:
M

mrtg

Здравствуйте Sinkopa!
СПС за то что откликнулись столь быстро и подробным, детальным ответом и примером.
Я изучаю ваш материал.
Я приблизительно подумывал сделать так:
1) Подключится ADO таблице
2) Экспортировать нужные нам данные в текст файл (типа готового SQL запроса )
3) Отключится от АДО
4) Подключится к MYSQL
5)
Код:
ZMySQLQuery.SQL.Text:= // дать обзор к этому файлу и выполнить как
 
// ZMySQLQuery.SQL.Text:=  будет работать как ADOCommand1.CommandText:=’’;
//ADOCommand1.Execute; или на него есть дрогой компонент
 
{а это  текст файла
INSERT INTO `CARS`.` CARS `
(`ID`,`Brand`,`Type`,`CC`,`PK`,`Cyl`,`KW`,`Price`,`Country`)
VALUES
(NULL, '1111111', '222222', '3333333', 'годен', 1', '202080000', '9002', '2015-02-01',)
(NULL, '1111111', '222222', '3333333', 'годен', 1', '202080000', '9002', '2015-02-01',)
……
….
текст файла
}
Может я не прав или это неудобный вариант.
Хочу узнать ваше мнение
 
S

sinkopa

Я изучаю ваш материал.
Я приблизительно подумывал сделать так:
...
Может я не прав или это неудобный вариант.
Хочу узнать ваше мнение

Извините не понимаю... :)
Я Вам изложил самый удобный и самый быстрый вариант переноса данных... что Вас в нем не устраивает? :)

2) Экспортировать нужные нам данные в текст файл (типа готового SQL запроса )

Не спрашиваю (хоть и хочется) нахрена это Вам надо... Только вот замечу, что в данном случае формулировать Вам следует не (типа готового SQL запроса ) а (типа скрипта - набора готовых SQL запросов )...
В один запрос MySQL может Вас "зарубить" по количеству допустимых байтов (буков) на один statement (исполняемый запрос).

При выполнение же скрипта (это делается через контрол TZSqlProcessor) с набором запросов, Вы получите ТО-НА-ТО что и в моём коде, только в несколько раз медленнее. :)

Мой же вариант работает В ОДНОЙ ТРАНЗАКЦИИ, а значит количество производимых вставок фактически не влияет на общее время их выполнения. Т.е. хоть 100 записей хоть 10000 записей вставятся в MySQL одинаково быстро...
Эх... да что уж теперь скромничать... Практически мгновенно они (в коде моём) вставляются... :) :)
Можете проверить...

PS.

TADOCommand это компонент из "другой оперы" и к ZeosDBO отношения не имеет.
В моём примере только компоненты ZeosDBO.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!