Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.135.219.166] |
|
Сообщ.
#1
,
|
|
|
Добрый день
Использую libmysql.dll (mysql.pas) Подключение установлено одновременно к 2 БД - локальной и внешней (LibHanLoc и LibHanRem) соответственно. По локальной гуляют большие объемы данных, из внешней используется только 1 таблица из которой берутся ID объектов. Был код такой (полностью рабочий) s:='INSERT INTO table1 (***) VALUES (***) ON DUPLICATE KEY UPDATE ***'; if mysql_query(LibHanRem, PAnsiChar(s)) <> 0 then begin writeln('Query error: '+mysql_error(LibHanRem)); exit; end; //получаем ID добавленного или существовавшего if mysql_query(LibHanRem, PAnsiChar('SELECT id FROM table1 WHERE *** LIMIT 1')) = 0 then mySQL_Res := mysql_store_result(LibHanRem); if mySQL_Res<>nil then try MYSQL_ROW := mysql_fetch_row(mySQL_Res); if MYSQL_ROW<>nil then begin val(MYSQL_ROW^[0],result,i); end; finally mysql_free_result(mySQL_Res); mySQL_Res := nil; end; Сейчас задача снизить количество запросов к LibHanRem, потому ID всех часто используемых объектов будут сохраняться в локальной копии table1 (таблица будет с тем же названием). Их на пару порядков меньше чем всего записей в table1 на удаленном сервере. Переписал код вот так: //запрашиваем в локальном кеше if mysql_query(LibHanLoc, PAnsiChar('SELECT id FROM table1 WHERE *** LIMIT 1')) = 0 then mySQL_Res := mysql_store_result(LibHanRem); if mySQL_Res<>nil then try //он здесь таки есть MYSQL_ROW := mysql_fetch_row(mySQL_Res); if MYSQL_ROW<>nil then begin val(MYSQL_ROW^[0],result,i); writeln('LOCAL CACHE ID : ',result); exit; //не будет утечек памяти? end; finally mysql_free_result(mySQL_Res); mySQL_Res := nil; end; //сюда попадаем если MYSQL_ROW=nil или mySQL_Res=nil значит в локальном кеше этого нет //добавляем или обновляем в основной базе writeln('CHECK MAIN DB'); s:='INSERT INTO table1 (***) VALUES (***) ON DUPLICATE KEY UPDATE ***'; if mysql_query(LibHanRem, PAnsiChar(s)) <> 0 then begin writeln('Query error: '+mysql_error(LibHanRem)); exit; end; //получаем ID добавленного или существовавшего if mysql_query(LibHanRem, PAnsiChar('SELECT id FROM table1 WHERE *** LIMIT 1')) = 0 then mySQL_Res := mysql_store_result(LibHanRem); if mySQL_Res<>nil then try MYSQL_ROW := mysql_fetch_row(mySQL_Res); if MYSQL_ROW<>nil then begin val(MYSQL_ROW^[0],result,i); writeln('MAIN DB ID: ',result); end; finally mysql_free_result(mySQL_Res); mySQL_Res := nil; end; if result>0 then begin s:='INSERT INTO table1 (***) VALUES (***)'; //вносим в локальный кеш запись и ключем - полученным из основной базы ID и параметрами для поиска if mysql_query(LibHanLoc, PAnsiChar(s)) <> 0 then begin writeln(s); writeln('Query error: '+mysql_error(LibHanLoc)); //возникает Commands out of sync; you can't run this command now, ничего не заносится end; end; В сети написано Цитата Это может произойти, например, если используется mysql_use_result() и делается попытка выполнить новый запрос до того, как вызвана mysql_free_result(), или если клиент пытается выполнить два возвращающих данные запроса без обращения к mysql_use_result() либо mysql_store_result() в промежутке между ними. Лажа возникает именно в последнем запросе к локальной базе, предыдущий запрос был но его результаты очищены. В этом запросе просто вносятся данные, их результат не запрашивается т.к. не нужен. Что с этим делать? P.S. приведен только код содержимого функции получения ID. В тестовом случае она вызывается только 1 раз, ошибка не из-за того что что-то произошло в предыдущем вызове потому не работает последующий. |