Обсуждение статьи "Работа с СУБД MySQL из MQL5 (MQL4)" - страница 7

 

Хорошо, я вижу, что вы написали советник для этих целей, и он написан без учета рекомендаций, которые я разместил в статье.

Итак, давайте двигаться шаг за шагом: 1.

1. вызов функции " DB = cMySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); " должен быть сделан внутри OnInit() вместо стандартной функции OnTick(). 2.

2. Вы используете cMySqlConnect - это импортированная функция из DLL, вы должны использовать функцию MySqlConnect вместо cMySqlConnect !

3. Вы должны вызвать функцию MySqlDisconnect внутри функции OnDeinit() stundard.

4. необходимо проверить идентификатор подключения к базе данных в стандартной функции OnTick(), чтобы убедиться, что подключение было успешным.

В итоге это будет выглядеть следующим образом.

... your code
int DB = -1; // идентификатор базы данных//--.
... your code
int OnInit()
{
   DB = MySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); 

   if (DB != -1)
    {
    // соединение успешно установлено!
    // здесь вы должны определить логику создания таблицы
   }
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
 {
 MySqlDisconnect(DB);
 }

void OnTick()
{
 // первая команда.
 if (DB==-1) return; // не предпринимайте никаких действий при отсутствии соединения

 // здесь ваш код без вызова cMySqlConnect
}
You have to rebuild your code based on the requirements of project, as I see the currently there is no clear logic, everything messed up.
 
elugovoy:

Хорошо, я вижу, что вы написали советник для этих целей, и он написан без учета рекомендаций, которые я разместил в статье.

Итак, давайте двигаться шаг за шагом: 1.

1. вызов функции " DB = cMySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); " должен быть сделан внутри OnInit() вместо стандартной функции OnTick(). 2.

2. Вы используете cMySqlConnect - это импортированная функция из DLL, вы должны использовать функцию MySqlConnect вместо cMySqlConnect !

3. Вы должны вызвать функцию MySqlDisconnect внутри функции OnDeinit() stundard.

4. необходимо проверить идентификатор подключения к базе данных в стандартной функции OnTick(), чтобы убедиться, что подключение было успешным.

В итоге все будет выглядеть так.

Спасибо, я попробую еще раз и сообщу результат.
 
elugovoy:

Хорошо, я вижу, что вы написали советник для этих целей, и он написан без учета рекомендаций, которые я разместил в статье.

Итак, давайте двигаться шаг за шагом: 1.

1. вызов функции " DB = cMySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); " должен быть сделан внутри OnInit() вместо стандартной функции OnTick(). 2.

2. Вы используете cMySqlConnect - это импортированная функция из DLL, вы должны использовать функцию MySqlConnect вместо cMySqlConnect !

3. Вы должны вызвать функцию MySqlDisconnect внутри функции OnDeinit() stundard.

4. необходимо проверить идентификатор подключения к базе данных в стандартной функции OnTick(), чтобы убедиться, что подключение было успешным.

В итоге это будет выглядеть так.

Я изменил шаг за шагом, но проблема все еще существует при использовании эксперта в одном mt4 для четырех или более символов. он печатает " Access violation read to 0x0000000B в '... .MQLMySQL.dll'
"

код приведен ниже

<--


#include <MQLMySQL.mqh

int MySqlErrorNumber; // номер последней ошибки MySQL

string MySqlErrorDescription; // описание ошибки


//+------------------------------------------------------------------+

//| Функция инициализации эксперта & nbsp; |

//+------------------------------------------------------------------+

int OnInit()

OnInit(); int OnInit()

EventSetTimer(timeSeconds);

DB = MySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); if( DB == -1 )

if( DB == -1 )

{

Print("База данных не подключена..."); if( DB == -1 ) { print("База данных не подключена... "); }

}

return(INIT_SUCCEEDED); }

}

//+------------------------------------------------------------------+

//| Функция деинициализации эксперта |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

{

MySqlDisconnect(DB);

EventKillTimer();

ObjectsDeleteAll();

}


void OnTimer()

{

//Alert(TimeCurrent());

OnTick();

}


//+------------------------------------------------------------------+

//| Экспертная функция тика & nbsp; |

//+------------------------------------------------------------------+

void OnTick()

{

if( DB == -1 )

{

Alert("База данных не подключена ... "); return; { Alert("База данных не подключена ...")

return; }

}

if( IsExpertEnabled() && IsConnected() && AccountNumber() > 0 && DB ! = -1 )

{

int account = AccountNumber();

string symbol = Symbol(); if( cmd !

if( cmd ! = "" && cmd ! = NULL )

{

symbol = cmd; }

}

symbolOrder = symbol + "_table";

double spread = (Ask - Bid); } symbolOrder = symbol + "_table"; }

прием = spread*MathPow(10, Digits).

//int DB = cMySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag);

Query = "SELECT * FROM " + symbol + " where AccountNumber = " + (string)AccountNumber();

//Print(Query);

int Cursor1 = MySqlCursorOpen(DB, Query);

if (Cursor1 >= 0)

{

int Rows1 = MySqlCursorRows(Cursor1); int Cursor1 = MySqlCursorOpen(DB, Query); if (Cursor1 >= 0)

int dataRows1 = Rows1;

//Alert(dataRows);

if( dataRows1 > 0 )

{

Query = "update " + symbol + " set Bid = " + (string)Bid + ", Ask = " + ( string)Ask

+ ", Spread = " + DoubleToStr(spread, Digits)

+ ", Time = '" + TimeToString(TimeLocal(), TIME_DATE|TIME_SECONDS ) + "', где AccountNumber = "

+ (string)account; // + + "' and Symbol = '" + symbol + "'".

MySqlExecute(DB, Query);

MySqlCursorClose(Cursor1);

}

else if( dataRows1 == 0 )

{

Query = "CREATE TABLE IF NOT EXISTS " + symbol + " (id int NOT NULL AUTO_ INCREMENT PRIMARY KEY, AccountNumber int, "

+ "Symbol char(20), Bid double, Ask double, Spread double,"

+ "Memo char(50), "

+ "Time datetime) ENGINE=MEMORY DEFAULT CHARSET=utf8 ";

MySqlExecute(DB, Query);

Query = "INSERT INTO " + symbol + "(AccountNumber, Symbol, Bid, Ask, Spread. Memo, Time) VALUES ("

+ (string)account + ", '" + symbol + "', "+ (string)Bid+", "+ (string)Ask + ", "

+ DoubleToStr(spread, Digits)

+ ", '" + (string)AccountCompany()

+ "', \'"+TimeToString(TimeLocal(), TIME_DATE|TIME_SECONDS)+"\')"";

if(MySqlExecute(DB, Query) ! = true )

{

//Query = "DROP TABLE IF EXISTS `data_table`";

//MySqlExecute(DB, Query);

Query = "CREATE TABLE IF NOT EXISTS " + symbol + "(id int NOT NULL AUTO_INCREMENT PRIMARY KEY, AccountNumber int, "

+ "Symbol char(20), Bid double, Ask double, Spread double,"

+ "Memo char(50), "

+ "Time datetime) ENGINE=MEMORY DEFAULT CHARSET= utf8 ";

MySqlExecute(DB, Query);

}

}

MySqlCursorClose(Cursor1); // НИКОГДА НЕ ЗАБУДЬТЕ ЗАКРЫТЬ КУРСОР !!!!

}

}

}

-->

 
elugovoy:

Хорошо, я вижу, что вы написали советник для этих целей, и он написан без учета рекомендаций, которые я разместил в статье.

Итак, давайте двигаться шаг за шагом: 1.

1. вызов функции " DB = cMySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); " должен быть сделан внутри OnInit() вместо стандартной функции OnTick(). 2.

2. Вы используете cMySqlConnect - это импортированная функция из DLL, вы должны использовать функцию MySqlConnect вместо cMySqlConnect !

3. Вы должны вызвать функцию MySqlDisconnect внутри функции OnDeinit() stundard.

4. необходимо проверить идентификатор подключения к базе данных в стандартной функции OnTick(), чтобы убедиться, что подключение было успешным.

В итоге это будет выглядеть так.

Проблема в том, что он не может использовать в одном mt4 более двух символов, если использовать только один символ, это нормально. При использовании четырех или более, он работает нормально, но через несколько минут, он печатает проблему "OnTick()". Через несколько минут выдает проблему "Access violation read to 0x0000000B in '...MQLMySQL.db'". .MQLMySQL.dll'".

Это все скрипты, они запускаются только один раз, вы можете попробовать один эксперт вызвать dll в четыре или более символов в одном или двух mt4, вы можете найти проблему.

Может быть, dll нуждается в выпуске memeoy или garbe collection?

 
MFC преждевременно сбрасывает утечки при выходе, вмест о того чтобы дождаться, пока
CRT сбросит утечки после статического уничтожения данных, и это приводит к &#959; ложным сообщениям об утечках для объектов, которые выделили память до инициализации MFC и которые таким образом уничтожаются после выхода MFC nbsp;
ложные сообщения об утечках для объектов, которые выделили память до инициализации MFC
и которые, таким образом, уничтожаются после выхода из MFC. Это
обычно наблюдается при использовании библиотеки MFC DLL в программе, которая также использует
библиотеку времени выполнения C++.
 

Еще раз здравствуйте.

Судя по предоставленному вами коду, я предполагаю, что вы новичок в MQL.

Извините, у меня нет времени учить вас, но у меня есть время на тестирование разработанного мной программного обеспечения.

Извините, у меня нет времени учить вас, но у меня есть время для тестирования программного обеспечения, которое я разработал. Итак, вот журналы прилагаются.

Построил для вас тестовый советник, основанный на вашей логике: каждая таблица определена для каждой валютной пары и может хранить данные онлайн рынка для разных счетов.

Вы можете просмотреть логи, ни одной ошибки "Access violation..." не возникло. Вы можете просмотреть журналы, ни одной ошибки "Access violation..." не возникло.

Проблема не в библиотеке MQLMySQL.

Тестируем советника.

//+------------------------------------------------------------------+
//|& nbsp; &nbsp ; DFTest.mq4 |
//|& nbsp; Copyright 2014, MetaQuotes Software Corp.|
//|& nbsp; &nbsp ; http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property strict
#include <MQLMySQL.mqh>

input string Host = "localhost";
input string User = "root";
input string Password = "ioctrl";
input string Database = "mysql";
input int Port = 3306;
input string Socket = "";
input int ClientFlag = 0;

input int Timer = 1; // Таймер (секунды) сейчас не используется

int DB;

int OnInit()
{
 SQLTrace = true; // чтобы увидеть все запросы, которые будут отправлены в базу данных
       EventSetTimer(Timer);
       DB = MySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); 
       if( DB == -1 )
       {
            Print("Database is not connected! Error: ", MySqlErrorDescription);
            return (INIT_FAILED);
       }
       
 // создайте таблицу, если она не существует
 string cmd;
 cmd = "CREATE TABLE IF NOT EXISTS `" + Symbol() + "` (id int NOT NULL AUTO_INCREMENT PRIMARY KEY, AccountNumber int, "
       + "Symbol char(20), Bid double, Ask double, Spread double, " 
       + "Memo char(50), " 
       + "Time datetime) ENGINE=MEMORY DEFAULT CHARSET=utf8";
 if (!MySqlExecute(DB, cmd))
    {
     Print ("Table creation error: ",MySqlErrorDescription);
     return (INIT_FAILED);
    }
                      

       return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
      MySqlDisconnect(DB); 
      EventKillTimer();
}


void OnTimer()
{
 // вы никогда не должны вызывать OnTick из OnTimer и наоборот.
 // цель этих двух функций различна
}

void OnTick()
{
 int account;
 string symbol;
 double spread;
 string Query, cmd;
 int Cursor;
 int Rows;
 
 if (DB == -1)
    {
    Comment("Database is not connected ... ");
    return;
    }

 if ( IsExpertEnabled() && IsConnected() && AccountNumber() > 0 )
    {
     account = AccountNumber();
     symbol = "`"+Symbol()+"`"; // если вы хотите использовать его в качестве имени таблицы, вы должны использовать кавычки, что является хорошей практикой для баз данных MySQL
     
 
 spread = (Ask - Bid);
 
 // возможно, было бы лучше использовать что-то вроде этого: admission = MarketInfo(symbol, MODE_SPREAD);
 Query = "SELECT * FROM " + symbol + " where AccountNumber = " + (string)account;
 Cursor = MySqlCursorOpen(DB, Query);
 if (Cursor >= 0)
    {
      Rows = MySqlCursorRows(Cursor);
      if ( Rows > 0 )
         {
          cmd = "update " + symbol + " set Bid = "+(string)Bid + ", Ask = " + (string)Ask
                       + ", Spread = " + DoubleToStr(spread, Digits)  
                       + ", Time = '" + TimeToString(TimeLocal(), TIME_DATE|TIME_SECONDS) +"' where AccountNumber = " + (string)account;
         }
      else
         {
          cmd = "INSERT INTO " + symbol + "(AccountNumber, Symbol, Bid, Ask, Spread, Memo, Time) VALUES (" 
                + (string)account + ", \'" + symbol + "\', "+DoubleToStr(Bid,Digits)+","+ DoubleToStr(Ask,Digits) + ","  + DoubleToStr(spread, Digits) 
                + ", \'" + AccountCompany() +"\', \'"+TimeToString(TimeLocal(), TIME_DATE|TIME_SECONDS)+"\')";
         }
      if (!MySqlExecute(DB, cmd))
         {
          Print("Updating error: ",MySqlErrorDescription);
          Print (cmd);
         }

      MySqlCursorClose(Cursor);
     }
  }

} 

 

Это правильная логика использования библиотеки.

В целях оптимизации можно даже не использовать оператор SELECT, а просто выполнить оператор UPDATE, а затем проверить, что (MySqlRowsAffected()==0) означает, что не было ни одной строки. У вас ~100% обновлений, поэтому примените оператор INSERT.

У вас ~100% обновлений, поэтому этот обходной путь может увеличить производительность и уменьшить сетевой трафик.

И в конце, к статье приложены полные исходные коды проекта (включая разработку DLL), вы можете изменить их по своему усмотрению.

Если вы все же обнаружили, что проблема в MqlMySQL.DLL, вы можете отладить ее и исправить самостоятельно.

С наилучшими пожеланиями, Евгений

Евгений

Файлы:
logs.zip  302 kb
 

Отличная работа, спасибо большое Евгению.

Ваши коды мне очень помогают, я могу сэкономить так много времени. Я попытался сделать INSERT, SELECT, UPDATE и DELETE запросы успешно. Если я не ошибаюсь, то "Курсор" нужен только для SELECT запроса ?

= pedma

//+------------------------------------------------------------------+
//|MySQL-006.mq4 |
//|Copyright 2014, Евгений Луговой |
//| http://www.fxcodexlab.com |
//| Запросы на выборку, вставку, обновление и удаление|
//| изменено : педма|
//+------------------------------------------------------------------+

#property copyright "Copyright 2014, Eugene Lugovoy."
#property link      "http://www.fxcodexlab.com"
#property version   "1.00"
#property strict

#include <MQLMySQL.mqh>

string INI;
//+------------------------------------------------------------------+
//| Функция запуска программы сценария|
//+------------------------------------------------------------------+
void OnStart() {
 string Host, User, Password, Database, Socket; // учетные данные базы данных
 int Port,ClientFlag;
 int DB; // идентификатор базы данных
 
 Print (MySqlVersion());

 INI = "C:\\This\\Must\\be\\Real\\Path\\To\\MyConnection.ini";
 
 // чтение учетных данных базы данных из INI-файла
 Host = ReadIni(INI, "MYSQL", "Host");
 User = ReadIni(INI, "MYSQL", "User");
 Password = ReadIni(INI, "MYSQL", "Password");
 Database = ReadIni(INI, "MYSQL", "Database");
 Port     = StrToInteger(ReadIni(INI, "MYSQL", "Port"));
 Socket   = ReadIni(INI, "MYSQL", "Socket");
 /// ClientFlag = StrToInteger(ReadIni(INI, "MYSQL", "ClientFlag")); 
 ClientFlag = CLIENT_MULTI_STATEMENTS;

 Print ("Host: ",Host, ", User: ", User, ", Database: ",Database);
 
 // откройте соединение с базой данных
 Print ("Connecting...");
 
 DB = MySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag);
 
 if (DB == -1) { Print ("Connection failed! Error: "+MySqlErrorDescription); return; } else { Print ("Connected! DBID#",DB);}
 
 // выполнение оператора SELECT
 string Query0,Query1,Query2,Query3,Query4,Query5,Query6,Query7;
 int    i,Cursor1,Cursor3,Cursor5,Cursor7,Rows,total;
 
 int      vId;
 string   vCode;
 datetime vStartTime;
 
 Query0 = "DROP TABLE IF EXISTS `test_table`";
 MySqlExecute(DB, Query0);
 
 Query0 = "CREATE TABLE `test_table` (id int, code varchar(50), start_date datetime)";
 if (MySqlExecute(DB, Query0))  {
     Print ("Table `test_table` created.");
 }
 else  {
     Print ("Table `test_table` cannot be created. Error: ", MySqlErrorDescription);
 }
 
 //--- вставка данных
 Query0 = "INSERT INTO `test_table` (id, code, start_date) VALUES ("+(string)AccountNumber()+",\'ACCOUNT\',\'"+TimeToStr(TimeLocal(), TIME_DATE|TIME_SECONDS)+"\')";
  if (MySqlExecute(DB, Query0))   {
      Print ("Succeeded: ", Query0);
  }
  else  {
      Print ("Error: ", MySqlErrorDescription);
      Print ("Query: ", Query0);
  }
  
  // multi-insert
  Query0 =          "INSERT INTO `test_table` (id, code, start_date) VALUES (1,\'EURUSD\',\'2014.01.01 00:00:01\');";
  Query0 = Query0 + "INSERT INTO `test_table` (id, code, start_date) VALUES (2,\'EURJPY\',\'2014.01.02 00:02:00\');";
  Query0 = Query0 + "INSERT INTO `test_table` (id, code, start_date) VALUES (3,\'USDJPY\',\'2014.01.03 03:00:00\');";
  if (MySqlExecute(DB, Query0))   {
      Print ("Succeeded! 3 rows has been inserted by one query.");
  }
  else  {
      Print ("Error of multiple statements: ", MySqlErrorDescription);
  }

 //--- выберите запрос, нужен курсор ----.
 Query1 = "SELECT id, code, start_date FROM `test_table`";
 Print ("SQL> ", Query1);
 Cursor1 = MySqlCursorOpen(DB, Query1);
 
 if (Cursor1 >= 0)  {
     Rows = MySqlCursorRows(Cursor1);
     Print (Rows, " row(s) selected.");
     for (i=0; i<Rows; i++) {
         if (MySqlCursorFetchRow(Cursor1))   {
             vId = MySqlGetFieldAsInt(Cursor1, 0); // id
             vCode = MySqlGetFieldAsString(Cursor1, 1); // код
             vStartTime = MySqlGetFieldAsDatetime(Cursor1, 2); // start_time
             Print ("ROW[",i,"]: id = ", vId, ", code = ", vCode, ", start_time = ", TimeToStr(vStartTime, TIME_DATE|TIME_SECONDS));
         }
         total += vId;
     }
     //--- вставьте данные на основе запроса
     Query2 = "INSERT INTO `test_table` (id, code, start_date) VALUES ("+(string)total+",\'ABCDEF\',\'"+TimeToStr(TimeLocal(), TIME_DATE|TIME_SECONDS)+"\');  ";
     if (MySqlExecute(DB, Query2))  {
         Print ("Succeeded! 1 new row has been inserted.");
     }
     else  {
         Print ("Error inserting data based on SELECT query : ", MySqlErrorDescription);
     }
     //---
     MySqlCursorClose(Cursor1); // НИКОГДА НЕ ЗАБЫВАЙТЕ ЗАКРЫВАТЬ КУРСОР!!!
 }
 else  {
     Print ("Cursor1 opening failed. Error: ", MySqlErrorDescription);
 }
     
 //--- новый курсор для выбора ---. 
 Query3 = "SELECT id, code, start_date FROM `test_table`";
 Print ("SQL> ", Query3);
 Cursor3 = MySqlCursorOpen(DB, Query3);
 if (Cursor3 >= 0)  {
     Rows = MySqlCursorRows(Cursor3);
     Print (Rows, " row(s) selected.");
     for (i=0; i<Rows; i++) {
         if (MySqlCursorFetchRow(Cursor3))   {
             vId = MySqlGetFieldAsInt(Cursor3, 0); // id
             vCode = MySqlGetFieldAsString(Cursor3, 1); // код
             vStartTime = MySqlGetFieldAsDatetime(Cursor3, 2); // start_time
             Print ("ROW[",i,"]: id = ", vId, ", code = ", vCode, ", start_time = ", TimeToStr(vStartTime, TIME_DATE|TIME_SECONDS));
         }
     }
     //--- обновить данные ----
     Query4 = "UPDATE `test_table` SET id=8,code='PQRXYZ',start_date=\'"+TimeToStr(TimeLocal(), TIME_DATE|TIME_SECONDS)+"\' WHERE code='ABCDEF';  ";
     if (MySqlExecute(DB, Query4))  {
         Print ("Succeeded! last row has been updated (code ABCDEF => PQRXYZ & new id=8.");
     }
     else  {
         Print ("Error updating data of last row : ", MySqlErrorDescription);
     }
     //---
     MySqlCursorClose(Cursor3); // НИКОГДА НЕ ЗАБЫВАЙТЕ ЗАКРЫВАТЬ КУРСОР!!!
 }
 else  {
     Print ("Cursor3 opening failed. Error: ", MySqlErrorDescription);
 }
 
 //--- покажите результат после обновления, нужен новый курсор ---- 
 Query5 = "SELECT id, code, start_date FROM `test_table`";
 Print ("SQL> ", Query5);
 Cursor5 = MySqlCursorOpen(DB, Query5);
 if (Cursor5 >= 0)  {
     Rows = MySqlCursorRows(Cursor5);
     Print (Rows, " row(s) selected.");
     for (i=0; i<Rows; i++) {
         if (MySqlCursorFetchRow(Cursor5))   {
             vId = MySqlGetFieldAsInt(Cursor5, 0); // id
             vCode = MySqlGetFieldAsString(Cursor5, 1); // код
             vStartTime = MySqlGetFieldAsDatetime(Cursor5, 2); // start_time
             Print ("ROW[",i,"]: id = ", vId, ", code = ", vCode, ", start_time = ", TimeToStr(vStartTime, TIME_DATE|TIME_SECONDS));
         }
     }
     //--- удалить запрос ---
     Query6 = "DELETE FROM `test_table` WHERE id=3;  ";
     if (MySqlExecute(DB, Query6))  {
         Print ("Succeeded! 1 row (id=3) has been deleted.");
     }
     else  {
         Print ("Error deleting 1 row : ", MySqlErrorDescription);
     }
     //---
     MySqlCursorClose(Cursor5); // НИКОГДА НЕ ЗАБЫВАЙТЕ ЗАКРЫВАТЬ КУРСОР!!!
 }
 else  {
     Print ("Cursor3 opening failed. Error: ", MySqlErrorDescription);
 }
 
 //--- показать результат после удаления, нужен другой курсор ---. 
 Query7 = "SELECT id, code, start_date FROM `test_table`";
 Print ("SQL> ", Query7);
 Cursor7 = MySqlCursorOpen(DB, Query7);
 if (Cursor7 >= 0)  {
     Rows = MySqlCursorRows(Cursor7);
     Print (Rows, " row(s) selected.");
     for (i=0; i<Rows; i++) {
         if (MySqlCursorFetchRow(Cursor7))   {
             vId = MySqlGetFieldAsInt(Cursor7, 0); // id
             vCode = MySqlGetFieldAsString(Cursor7, 1); // код
             vStartTime = MySqlGetFieldAsDatetime(Cursor7, 2); // start_time
             Print ("ROW[",i,"]: id = ", vId, ", code = ", vCode, ", start_time = ", TimeToStr(vStartTime, TIME_DATE|TIME_SECONDS));
         }
     }
     //---
     MySqlCursorClose(Cursor7); // НИКОГДА НЕ ЗАБЫВАЙТЕ ЗАКРЫВАТЬ КУРСОР!!!
 }
 else  {
     Print ("Cursor3 opening failed. Error: ", MySqlErrorDescription);
 }
 //----- в конце ---- 
 MySqlDisconnect(DB);
 Print ("Disconnected. Script done!");
}
//+------------------------------------------------------------------+




 
pedma:

Отличная работа, спасибо большое Евгению.

Ваши коды мне очень помогают, я могу сэкономить так много времени. Я попытался сделать INSERT, SELECT, UPDATE и DELETE запросы успешно. Если я не ошибаюсь, то "Курсор" нужен только для SELECT запроса ?

= pedma




Именно так!

Курсоры используются только для выбора данных, потому что мы должны получать данные из БД в переменную MQL, а не просто отправлять sql-команду в БД.

Я рад, что мое решение помогло вам.

Удачи,

Евгений

 

Привет, Евгений,

Мне просто интересно, занимаетесь ли вы еще платными проектами по разработке, так как я хочу создать копировщик удаленной торговли, который будет интегрирован в советник, который я буду продавать?

Я посмотрел на Upwork, и, похоже, вы не выполняли никаких проектов для фрилансеров в последнее время.

Я попробовал сам, используя созданную вами библиотеку, но получилось не очень хорошо. Хотя я уверен, что для человека с вашими способностями к программированию это не составит труда!

Заранее спасибо,

Джеймс

 
James Beach:

Привет, Евгений,

Мне просто интересно, занимаетесь ли вы еще платными проектами по разработке, так как я хочу создать копировщик удаленной торговли, который будет интегрирован в советник, который я буду продавать?

Я посмотрел на Upwork, и, похоже, вы не выполняли никаких проектов для фрилансеров в последнее время.

Я попробовал сам, используя созданную вами библиотеку, но получилось не очень хорошо. Хотя я уверен, что для человека с вашими способностями к программированию это не составит труда!

Заранее спасибо,

Джеймс

Здравствуйте, Джеймс,

В настоящее время я работаю на Upwork только над одним большим проектом. Поэтому сейчас у меня нет много свободного времени. Какие у вас проблемы с либами? Чем я могу вам помочь?