TSQLQuery + MySQL

Модератор: Модераторы

TSQLQuery + MySQL

Сообщение VirtUX » 29.04.2014 22:49:47

Делаю запрос
Код: Выделить всё
select `name`,`count`,`place`,`procearned`,`period_to`,`numbercar`,`vincode`,`numberpasp`,`year_make`,`maker`,`vladeler`,`datedocto`,`datedoctoend` from cars

в консоли показывает все 51 запись. TSQLQuery возвращает только 10! В чем может быть проблема?
Как работает запрос:
Код: Выделить всё
function TDBConnect.DoAnySQL(SQL: TStringList): integer;
var
  i, fi, fc: integer;
  ss: string;
begin

  if SQL = nil
  then begin
    Result := -1;
    exit;
  end;

  fSQLQuery.sql.Text := SQL.Text;
  fSQLQuery.Open;
  Result := fSQLQuery.RecordCount;
  if Result > 0
  then begin
    SQL.Clear;
    fc := pred(fSQLQuery.FieldCount);
    for i := 1 to Result
    do begin

      ss := '';

      for fi := 0 to fc do ss += fSQLQuery.Fields[fi].AsString + #1;

      Delete(ss, Length(ss), 1);
      SQL.Append(ss);
      fSQLQuery.Next;

    end;
  end;

  fSQLQuery.Close;

end;       


Добавлено спустя 43 минуты 53 секунды:
И еще. В этой же таблице пытаюсь обновить запись
Код: Выделить всё
function TFormDirectorEditCar.DoEdit: boolean;
begin

  Result := false;

  if ComboBoxPlaces.ItemIndex < 0 then
  begin
    ShowMessage('Не выбрано место пребывания!');
    exit;
  end;

  ClientConn.Connect.ExecAnySQL('update cars set `count`='+#39+IntToStr(SpinEditKolvo.Value)+#39+
                                ',`place`='+#39+ComboBoxPlaces.Text+#39+
                                ',`procearned`='+#39+IntToStr(SpinEditProcZP.Value)+#39+
                                ',`period_to`='+#39+IntToStr(SpinEditPeriod.Value)+#39+
                                ',`numbercar`='+#39+EditGosN.Text+#39+
                                ',`vincode`='+#39+EditVIN.Text+#39+
                                ',`numberpasp`='+#39+EditPasp.Text+#39+
                                ',`year_make`='+#39+IntToStr(SpinEditYOut.Value)+#39+
                                ',`maker`='+#39+EditMaker.Text+#39+
                                ',`vladeler`='+#39+EditVladelec.Text+#39+
                                ',`datedocto`='+#39+DateTimeToStr(DateEditTalonDate.Date)+#39+
                                ',`datedoctoend`='+#39+DateTimeToStr(DateEditTalonTo.Date)+#39+
                                ' where `name`='+#39+EditCar.Text+#39+
                                ' limit 1');


  UpdateGrid;

  Result := true;

end;                   

В таблице обновляется. Т.е.
Код: Выделить всё
procedure TFormDirectorEditCar.UpdateGrid;
var
  cou, i, ci: integer;
  sl: TStringList;
  nowS: string;
begin

  { Очистили таблицу }
  StringGrid1.RowCount:=1;

  sl := TStringList.Create;

  sl.Text:= 'select `name`,`count`,`place`,`procearned`,`period_to`,`numbercar`,`vincode`,`numberpasp`,`year_make`,`maker`,`vladeler`,`datedocto`,`datedoctoend` from cars';
  cou := ClientConn.Connect.DoAnySQL(sl);

  if cou > 0 then
  begin

     StringGrid1.RowCount:= succ(cou);
     for i := 1 to cou
     do begin
        nowS:= sl[pred(i)];
        for ci := 0 to 12
            do StringGrid1.Cells[ci, i] := LSGet(nowS, succ(ci));
     end;

  end;

  sl.Free;

end; 

я вижу, что данные обновились. Но реально, они остаются прежними. TSQLQuery не связан DB-компанентами. Я его использую для простых запросов к MySQL.

Добавлено спустя 25 минут 30 секунд:
С количеством записей разобрался. За это отвечает параметр "PacketRecords". Но возник другой вопрос: как загрузить, скажем, 1000 записей, если "PacketRecords" равен 100?
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 825
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: TSQLQuery + MySQL

Сообщение sign » 30.04.2014 06:39:03

Полагаться на количество записей?
Никогда на такое не шёл и не дай бог.

Универсальное, непробиваемое и вечное:
Код: Выделить всё
fSQLQuery.Open;
while not fSQLQuery.EOF do begin
   ...
  fSQLQuery.Next;
end;


Добавлено спустя 3 минуты 25 секунд:
VirtUX писал(а):как загрузить, скажем, 1000 записей,

Ну, так и загружайте эту 1000 записей, а не извращайтесь.

Код: Выделить всё
SELECT *
  FROM fSQLQuery
  LIMIT 1000


Добавлено спустя 16 минут 16 секунд:
Пользуйтесь для обновления простым, проверенным методом:

Код: Выделить всё
  qTmp1.Clear;
  qTmp1.SQL.Add('UPDATE cars SET ' +
                ' `count`=:count ' +
                ',`place`=:place ' +
                ',`procearned`=:procearned ' +
                ',`period_to`=:peroid ' +
                ',`numbercar`=:numbercar ' +
                ',`vincode`=:vincode ' +
                ',`numberpasp`=:numberpasp ' +
                ',`year_make`=:year_make ' +
                ',`maker`=:maker ' +
                ',`vladeler`=:vladeler ' +
                ',`datedocto`=:datedocto ' +
                ',`datedoctoend`=:datedoctoend ' +
                ' where `name`=:name ');
  qTmp1.ParamByName('count').AsInteger         := SpinEditKolvo.Value;
  qTmp1.ParamByName('place').AsString          := ComboBoxPlaces.Text;
  qTmp1.ParamByName('procearned').AsInteger    := SpinEditProcZP.Value;
  qTmp1.ParamByName('period_to').AsInteger     := SpinEditPeriod.Value;
  qTmp1.ParamByName('numbercar').AsString      := EditGosN.Text;
  qTmp1.ParamByName('vincode').AsString        := EditVIN.Text;
  qTmp1.ParamByName('numberpasp').AsString     := EditPasp.Text;
  qTmp1.ParamByName('year_make').AsInteger     := SpinEditYOut.Value;
  qTmp1.ParamByName('maker').AsString          := EditMaker.Text;
  qTmp1.ParamByName('vladeler').AsString       := EditVladelec.Text;
  qTmp1.ParamByName('datedocto').AsDateTime    := DateEditTalonDate.Date;
  qTmp1.ParamByName('datedoctoend').AsDateTime := DateEditTalonTo.Date;
  qTmp1.ParamByName('name').AsString           := EditCar.Text;
  qTmp1.ExecSQL;
sign
энтузиаст
 
Сообщения: 821
Зарегистрирован: 30.08.2009 09:20:53

Re: TSQLQuery + MySQL

Сообщение VirtUX » 30.04.2014 10:21:44

sign писал(а):Универсальное, непробиваемое и вечное:

Код: Выделить всё
fSQLQuery.Open;
while not fSQLQuery.EOF do begin
...
fSQLQuery.Next;
end;


Работет :)
Сделал так:
Код: Выделить всё
fSQLQuery.sql.Text := SQL.Text;
  fSQLQuery.Open;
  fSQLQuery.Last;
  Result := fSQLQuery.RecordCount;
  fSQLQuery.First;
  if Result > 0
  then begin
    SQL.Clear;
    fc := pred(fSQLQuery.FieldCount);
    while not fSQLQuery.EOF
    do begin

      ss := '';

      for fi := 0 to fc do ss += fSQLQuery.Fields[fi].AsString + #1;

      Delete(ss, Length(ss), 1);
      SQL.Append(ss);
      fSQLQuery.Next;

    end;
  end;

  fSQLQuery.Close;     

Спасибо!
Добавлено спустя 1 минуту 41 секунду:
sign писал(а):Пользуйтесь для обновления простым, проверенным методом:

Скажите: а что у Вас изменилось, в отличие от моего способа?.. Какая разница как формировать запрос?

Добавлено спустя 1 час 16 минут 9 секунд:
Написал отдельную процедуру для обновления данных:
Код: Выделить всё
procedure TDBConnect.UpdateSQL(SQL: string);
begin

  if SQL = '' then exit;

  fSQLQuery.UpdateSQL.Text := SQL;
  fSQLQuery.Open;
  fSQLQuery.Edit;
  fSQLQuery.Post;
  fSQLQuery.ApplyUpdates;

  fSQLQuery.Close;
  fSQLTransaction.Commit;

end;

Так работает :)

Добавлено спустя 10 минут 4 секунды:
Или так:
Код: Выделить всё
procedure TDBConnect.UpdateSQL(SQL: string);
begin

  if SQL = '' then exit;

  fSQLQuery.SQL.Text := SQL;
  fSQLQuery.ExecSQL;
  fSQLQuery.Close;
  fSQLTransaction.Commit;

end; 

Тоже работает
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 825
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: TSQLQuery + MySQL

Сообщение sign » 30.04.2014 14:49:04

VirtUX писал(а):Скажите: а что у Вас изменилось, в отличие от моего способа?.. Какая разница как формировать запрос?

Я раньше тоже так думал, пока пару раз тэйблом об фэйс не случилось.
Мой способ гарантирует приведение данных во внутренний формат.
sign
энтузиаст
 
Сообщения: 821
Зарегистрирован: 30.08.2009 09:20:53

Re: TSQLQuery + MySQL

Сообщение VirtUX » 20.08.2014 17:35:46

Дабы не плодить новую тему, пушу тут.
После обновления MariaDB стал получать ошибку:
TMySQL56Connection can not work with the installed MySQL client version: Expected (5.6), got (10.0.12-MariaDB).

устанавливал клиента 5.6 - не помогает. MariaDB внутри поддерживает и 5,5 и 5,6 вроде как... Что изменилось в этой Машке?
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 825
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: TSQLQuery + MySQL

Сообщение Максим » 21.08.2014 00:08:25

Версию они поменяли. Пишите в багтрекер FPC.
Аватара пользователя
Максим
энтузиаст
 
Сообщения: 588
Зарегистрирован: 27.07.2007 01:51:43
Откуда: Москва

Re: TSQLQuery + MySQL

Сообщение VirtUX » 21.08.2014 07:52:39

Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 825
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: TSQLQuery + MySQL

Сообщение Максим » 22.08.2014 03:06:48

Спасибо. Lazarus тут не при делах, переместил в раздел FPC.
Аватара пользователя
Максим
энтузиаст
 
Сообщения: 588
Зарегистрирован: 27.07.2007 01:51:43
Откуда: Москва

Re: TSQLQuery + MySQL

Сообщение Ism » 22.08.2014 23:57:08

У TSQLQuery есть свойство SQLQuery1.PacketRecords равное 10 , то есть минимум строк получаемых при открытии
Ism
энтузиаст
 
Сообщения: 900
Зарегистрирован: 06.04.2007 17:36:08

Re: TSQLQuery + MySQL

Сообщение VirtUX » 25.08.2014 18:57:20

Пока разработчики решают как свести MariaDB 10.0.X с MySQL 5.X по версиям...
Решение для фанатов роллинг-релиза openSuSE Factory от 16.08.2014 и выше (а так же для всех у кого MariaDB 10.0.X):
1. Проверяем наличие, и при отсутствии устанавливаем пакет libmysql56client18.
2. Ищем в /usr/lib64/ симлинк libmysqlclient.so.18 на libmysqlclient.so.18.0.0 (это из пакета libmysqlclient18). И если находим его, то удаляем.
3. Создаем нужный симлинк на библиотеку /usr/lib64/libmysql56client.so.18.1.0 или на ее имеющийся симлинк /usr/lib64/libmysql56client.so.18 (я делаю на ее симлинк):
Код: Выделить всё
ln -s /usr/lib64/libmysql56client.so.18 /usr/lib64/libmysqlclient.so.18

Готово.
Т.о. мы заменяем симлинк на библиотеку от MariaDB, на симлинк MySQL 5.6.
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 825
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: TSQLQuery + MySQL

Сообщение VirtUX » 12.09.2014 10:14:11

Всплыла неприятность в виде потери коннекта с БД, при долгом отсутствии запросов.
Устанавливаю соединение в классе-коннекторе один раз при старте программы/сервера таким образом:
Код: Выделить всё
constructor UFMySQLConnector.Create(nameDB, host, login, passwd: string);
begin
  fSQLQuery := TSQLQuery.Create(nil);
  fSQLTransaction := TSQLTransaction.Create(nil);

  fMySQLConnection := TMySQL55Connection.Create(nil);

  fMySQLConnection.Transaction := fSQLTransaction;
  fSQLTransaction.DataBase := fMySQLConnection;
  fSQLQuery.DataBase := fMySQLConnection;
  fSQLQuery.Transaction := fSQLTransaction;

  fMySQLConnection.HostName := host;
  fMySQLConnection.UserName := login;
  fMySQLConnection.Password := passwd;
  fMySQLConnection.DatabaseName := nameDB;

  fSQLTransaction.Active:= true;
  if not fMySQLConnection.Connected then fMySQLConnection.Open;
  fSQLQuery.Close;
  fSQLQuery.ParseSQL:= false;
  fSQLQuery.ReadOnly:= False;
  fSQLQuery.UpdateMode:= upWhereAll;
  ExecAnySQL('SET NAMES utf8'); // Это выполнение запроса внутри этого класса
end;         

По закрытии программы/сервера в деструкторе класса-коннектора уничтожаю:
Код: Выделить всё
destructor UFMySQLConnector.Destroy;
begin
  fMySQLConnection.Free;
  fSQLTransaction.Free;
  fSQLQuery.Free;

  inherited Destroy;
end;   

Можно вынести в отдельные процедуры весь этот код коннекта/дисконнекта и дергать их при отсутствии связи. Но...
1. Что конкретно отвечает за установку и поддержку связи с MySQL? Или: что нужно передёрнуть, чтоб связь возобновилась?
2. Каким образом можно узнать об отсутствии связи? В данный момент я узнаю об этом, когда не получаю ответа на запрос. Но может есть параметр-флаг отвечающий за наличие коннекта?
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 825
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: TSQLQuery + MySQL

Сообщение Ism » 12.09.2014 13:38:19

У mysql есть опция реконнекта
Попробуйте в параметрах соединения MYSQL_OPT_RECONNECT=1
Но надо проверять, параметр может быть проигнорирован
Ism
энтузиаст
 
Сообщения: 900
Зарегистрирован: 06.04.2007 17:36:08

Re: TSQLQuery + MySQL

Сообщение VirtUX » 12.09.2014 14:11:42

Нарыл следующее:
TSQLConnection.Connected
Is a connection to the server active or not

Description

Connected indicates whether a connection to the server is active or not. No queries to this server can be activated as long as the value is False

Setting the property to True will attempt a connection to the database DatabaseName on host HostName using the credentials specified in UserName and Password. If the connection or authentication fails, an exception is raised. This has the same effect as calling Open.

Setting the property to False will close the connection to the database. All datasets connected to the database will be closed, all transactions will be closed as well. This has the same effect as calling Close

и:
TSQLConnection.KeepConnection
Attempt to keep the connection open once it is established.

Description

KeepConnection can be used to attempt to keep the connection open once it is established. This property is currently not implemented.


Т.е.: при начальном подключении устанавливаем:
Код: Выделить всё
fMySQLConnection.KeepConnection := true;

и надеемся, что соединение будет поддержано надлежащим образом. НО! При каждом вызове процедуры отправки запроса на сервер, внутри нее делаем проверку:
Код: Выделить всё
if not fMySQLConnection.Connected then fMySQLConnection.Open;


Добавлено спустя 49 минут 36 секунд:
Оказалось, что fMySQLConnection.Connected остается в true даже при обрыве связи. И после восстановления связи ошибка соединения с БД не исчезает. Выкрутился пока так:
Код: Выделить всё
try
    fSQLQuery.Open;
  except
    fMySQLConnection.Close(true);
    try
      fMySQLConnection.Open;
      fSQLQuery.Open;
    except
      Result := -2;  { Сообщение об ошибке }
      Exit;
    end;
  end;

это в процедуре, выполняющей простой запрос на выборку данных.
Соответственно в процедуре внесения изменений:
Код: Выделить всё
try
    fSQLQuery.ExecSQL;
  except
    fMySQLConnection.Close(true);
    try
      fMySQLConnection.Open;
      fSQLQuery.ExecSQL;
    except
      Result := -2;
      Exit;
    end;
  end; 
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 825
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: TSQLQuery + MySQL

Сообщение Ism » 12.09.2014 15:46:34

Может лучше это настроить http://dev.mysql.com/doc/connector-pyth ... -ping.html
По идее если включить пинг в клиентской библиотеке, она будет проверять соединение и переподключаться
Ism
энтузиаст
 
Сообщения: 900
Зарегистрирован: 06.04.2007 17:36:08

Re: TSQLQuery + MySQL

Сообщение VirtUX » 14.09.2014 09:35:22

Я думаю, что лучше делать проверку при отправке запроса. Т.к.: нет запроса, значит нам по... до состояния подключения, и никого не напрягаем. Т.к.: во время отправки запроса, пинг мог быть еще не выполнен, а соединение уже отсутствовать; или уменьшать таймаут пинга, что вызовет не нужный напряг, да и не гарантирует наличие соединения во время отправки запроса в любом случае.
ИМХО.
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 825
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

След.

Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Рейтинг@Mail.ru