Discussão do artigo "Como acessar o banco de dados MySQL a partir do MQL5 (MQL4)" - página 7

 

Ok, vejo que você criou um consultor especialista para esse fim e ele foi criado sem as recomendações que publiquei no artigo.

Então, vamos seguir passo a passo: 1.

1) A chamada de " DB = cMySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); " deve ser feita dentro da função padrão OnInit() em vez de OnTick(). 2.

2) Você está usando cMySqlConnect - é uma função importada da DLL, você precisa usar a função MySqlConnect em vez de função cMySqlConnect !

3. você precisa chamar a função MySqlDisconnect dentro da função padrão OnDeinit().

4. você deve verificar o identificador de conexão do banco de dados dentro da função padrão OnTick() para ter certeza de que a conexão foi bem-sucedida.

Por fim, o resultado será semelhante a.

... your code
int DB = -1; // identificador do banco de dados//--
... your code
int OnInit()
{
   DB = MySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); 

   if (DB != -1)
    {
    // a conexão foi bem-sucedida!
    // aqui você precisa definir a lógica de criação da tabela
   }
   return(INIT_SUCCEEDED);
}

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

void OnTick()
{
 // primeiro comando.
 if (DB==-1) return; // não realizar nenhuma ação quando não houver conexão

 // aqui seu código sem a chamada 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:

Ok, vejo que você criou um consultor especialista para esse fim e ele foi criado sem as recomendações que publiquei no artigo.

Então, vamos seguir passo a passo: 1.

1) A chamada de " DB = cMySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); " deve ser feita dentro da função padrão OnInit() em vez de OnTick(). 2.

2) Você está usando cMySqlConnect - é uma função importada da DLL, você precisa usar a função MySqlConnect em vez de função cMySqlConnect !

3. você precisa chamar a função MySqlDisconnect dentro da função padrão OnDeinit().

4. você deve verificar o identificador de conexão do banco de dados dentro da função padrão OnTick() para ter certeza de que a conexão foi bem-sucedida.

Finalmente, o resultado será semelhante.

Obrigado, tentarei novamente e lhe darei o resultado.
 
elugovoy:

Ok, vejo que você criou um consultor especialista para esse fim e ele foi criado sem as recomendações que publiquei no artigo.

Então, vamos seguir passo a passo: 1.

1) A chamada de " DB = cMySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); " deve ser feita dentro da função padrão OnInit() em vez de OnTick(). 2.

2) Você está usando cMySqlConnect - é uma função importada da DLL, você precisa usar a função MySqlConnect em vez de função cMySqlConnect !

3) Você precisa chamar a função MySqlDisconnect dentro da função padrão OnDeinit().

4. você deve verificar o identificador de conexão do banco de dados dentro da função padrão OnTick() para ter certeza de que a conexão foi bem-sucedida.

Finalmente, o resultado será semelhante.

Eu mudei passo a passo, mas o problema ainda existe quando uso o expert em um mt4 para quatro ou mais símbolos. ele imprime " Access violation read to 0x0000000B em '... .MQLMySQL.dll'
"

O código é o seguinte

<--


#include <MQLMySQL.mqh

int MySqlErrorNumber; // número de erro recente do MySQL

string MySqlErrorDescription; // descrição do erro


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

//| Função de inicialização especializada & nbsp; |

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

int OnInit()

OnInit(); int OnInit()

EventSetTimer(timeSeconds);

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

if( DB == -1 )

{

Print("O banco de dados não está conectado..."); if( DB == -1 ) { print("O banco de dados não está conectado... "); }

}

return(INIT_SUCCEEDED); }

}

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

//| Função de desinicialização especializada |

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

void OnDeinit(const int reason)

{

MySqlDisconnect(DB);

EventKillTimer();

ObjectsDeleteAll();

}


void OnTimer()

{

//Alertar(TimeCurrent());

OnTick();

}


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

//| Função Expert tick & nbsp; |

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

void OnTick()

{

if( DB == -1 )

{

Alert("O banco de dados não está conectado... "); return; { Alert("O banco de dados não está conectado...")

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"; }

admissão = 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;

//Alerta(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 ) + "' where 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)+"\')"";

Se(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); // NUNCA ESQUEÇA DE FECHAR O CURSOR !!!!

}

}

}

-->

 
elugovoy:

Ok, vejo que você criou um consultor especialista para esse fim e ele foi criado sem as recomendações que publiquei no artigo.

Então, vamos seguir passo a passo: 1.

1) A chamada de " DB = cMySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); " deve ser feita dentro da função padrão OnInit() em vez de OnTick(). 2.

2) Você está usando cMySqlConnect - é uma função importada da DLL, você precisa usar a função MySqlConnect em vez de função cMySqlConnect !

3. você precisa chamar a função MySqlDisconnect dentro da função padrão OnDeinit().

4. você deve verificar o identificador de conexão do banco de dados dentro da função padrão OnTick() para ter certeza de que a conexão foi bem-sucedida.

Finalmente, o resultado será semelhante.

O problema é que ele não pode ser usado em um mt4 para mais de dois símbolos; se for usado em apenas um símbolo, está normal; quando usado em quatro ou mais, funciona bem, mas, após alguns minutos, ele imprime o problema "OnTick()". Depois de alguns minutos, ele imprime o problema "Access violation read to 0x0000000B in '...MQLMySQL.db'". .MQLMySQL.dll'"

Você pode tentar um especialista chamar a dll em quatro ou mais símbolos em um ou dois mt4, talvez encontre o problema.

Será que a dll precisa de uma versão memeoy ou de uma coleção de garbe?

 
O MFC descarta vazament os prematuramente quando sai, em vez de esperar que o
CRT descarregue vazamentos ap ós a destruição de dados estáticos, e isso causa "relatórios de vazamento espúrios do para objetos que alocaram memória antes da inicialização do MFC e que, portanto, são destruídos após a saída do MFC". nbsp;
relatórios de vazamentos espúrios para objetos que alocaram memória antes da inicialização do MFC
e que, portanto, são destruídos após a saída do MFC. Isso é
comumente observado ao usar a DLL do MFC em um programa que também usa
a DLL de tempo de execução do C++.
 

Olá mais uma vez.

Com base no código que você forneceu, acho que você é novo em MQL.

Desculpe-me, não tenho tempo para ensiná-lo, mas tenho tempo para testar o software que desenvolvi.

Desculpe-me, não tenho tempo para ensiná-lo, mas tenho tempo para testar o software que desenvolvi. Portanto, aqui estão os registros anexados.

Criei um EA de teste para você, com base em sua lógica: cada tabela definida para cada par de moedas e pode manter os dados do mercado on-line para diferentes contas.

Você pode inspecionar os registros, nenhum erro "Access violation..." foi gerado. Você pode inspecionar os registros, nenhum erro "Access violation..." foi levantado.

O problema não está na biblioteca MQLMySQL.

Testando o EA.

//+------------------------------------------------------------------+
//|& 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; // Temporizador (segundos) não usado agora

int DB;

int OnInit()
{
 SQLTrace = true; // para ver todas as consultas que seriam enviadas ao banco de dados
       EventSetTimer(Timer);
       DB = MySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); 
       if( DB == -1 )
       {
            Print("Database is not connected! Error: ", MySqlErrorDescription);
            return (INIT_FAILED);
       }
       
 // criar tabela se não existir
 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()
{
 // você nunca deve chamar OnTick de OnTimer e vice-versa.
 // o objetivo dessas duas funções é diferente
}

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()+"`"; // se você tiver que usá-lo como nome de tabela, deverá usar aspas como uma boa prática para o banco de dados MySQL
     
 
 spread = (Ask - Bid);
 
 // É possível que seja melhor usar algo assim: 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);
     }
  }

} 

 

Essa é a lógica correta do uso da biblioteca.

Devido à otimização, você pode até mesmo não usar a instrução SELECT, apenas executar a instrução UPDATE e, em seguida, verificar se (MySqlRowsAffected()==0) significa que nenhuma linha foi afetada. Você tem ~100% de atualizações, portanto, aplique o comando INSERT.

Como você tem cerca de 100% das atualizações, essa solução alternativa pode aumentar o desempenho e reduzir o tráfego da rede.

E, no final, os códigos-fonte completos do projeto (incluindo o desenvolvimento da DLL) foram anexados ao artigo, para que você possa alterá-los de sua própria maneira.

Se você achar que o problema está no MqlMySQL.DLL, poderá depurá-lo e corrigi-lo por conta própria.

Parabéns, Eugene

Eugênio

Arquivos anexados:
logs.zip  302 kb
 

Excelente trabalho, muito obrigado , Eugeniy.

Seus códigos me ajudam muito e posso economizar muito tempo. Tentei fazer consultas INSERT, SELECT, UPDATE e DELETE com sucesso. Se não estou enganado, o "Cursor" é necessário apenas para a consulta SELECT ??

= pedma

//+------------------------------------------------------------------+
//|MySQL-006.mq4
//|Direitos autorais 2014, Eugene Lugovoy |
//| http://www.fxcodexlab.com
//| Consulta de seleção, inserção, atualização e exclusão|
//| modificado por : pedma|
//+------------------------------------------------------------------+

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

#include <MQLMySQL.mqh>

string INI;
//+------------------------------------------------------------------+
//| Função de início do programa de script|
//+------------------------------------------------------------------+
void OnStart() {
 string Host, User, Password, Database, Socket; // credenciais do banco de dados
 int Port,ClientFlag;
 int DB; // identificador do banco de dados
 
 Print (MySqlVersion());

 INI = "C:\\This\\Must\\be\\Real\\Path\\To\\MyConnection.ini";
 
 // leitura das credenciais do banco de dados do arquivo 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);
 
 // abrir conexão com o banco de dados
 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);}
 
 // executando o comando 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);
 }
 
 //--- inserindo dados
 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-inserção
  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);
  }

 //--- consulta de seleção, precisa do Cursor ----
 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); // código
             vStartTime = MySqlGetFieldAsDatetime(Cursor1, 2); // start_time
             Print ("ROW[",i,"]: id = ", vId, ", code = ", vCode, ", start_time = ", TimeToStr(vStartTime, TIME_DATE|TIME_SECONDS));
         }
         total += vId;
     }
     //--- inserir dados com base na consulta
     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); // NUNCA SE ESQUEÇA DE FECHAR O CURSOR !!!
 }
 else  {
     Print ("Cursor1 opening failed. Error: ", MySqlErrorDescription);
 }
     
 //--- novo Cursor para seleção --- 
 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); // código
             vStartTime = MySqlGetFieldAsDatetime(Cursor3, 2); // start_time
             Print ("ROW[",i,"]: id = ", vId, ", code = ", vCode, ", start_time = ", TimeToStr(vStartTime, TIME_DATE|TIME_SECONDS));
         }
     }
     //--- atualizar dados ----
     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); // NUNCA SE ESQUEÇA DE FECHAR O CURSOR !!!
 }
 else  {
     Print ("Cursor3 opening failed. Error: ", MySqlErrorDescription);
 }
 
 //--- mostrar o resultado após a atualização, é necessário um novo cursor ---- 
 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); // código
             vStartTime = MySqlGetFieldAsDatetime(Cursor5, 2); // start_time
             Print ("ROW[",i,"]: id = ", vId, ", code = ", vCode, ", start_time = ", TimeToStr(vStartTime, TIME_DATE|TIME_SECONDS));
         }
     }
     //--- excluir consulta ---
     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); // NUNCA SE ESQUEÇA DE FECHAR O CURSOR !!!
 }
 else  {
     Print ("Cursor3 opening failed. Error: ", MySqlErrorDescription);
 }
 
 //--- mostrar o resultado após a exclusão, outro cursor é necessário --- 
 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); // código
             vStartTime = MySqlGetFieldAsDatetime(Cursor7, 2); // start_time
             Print ("ROW[",i,"]: id = ", vId, ", code = ", vCode, ", start_time = ", TimeToStr(vStartTime, TIME_DATE|TIME_SECONDS));
         }
     }
     //---
     MySqlCursorClose(Cursor7); // NUNCA SE ESQUEÇA DE FECHAR O CURSOR !!!
 }
 else  {
     Print ("Cursor3 opening failed. Error: ", MySqlErrorDescription);
 }
 //----- no final ---- 
 MySqlDisconnect(DB);
 Print ("Disconnected. Script done!");
}
//+------------------------------------------------------------------+




 
pedma:

Excelente trabalho, muito obrigado , Eugeniy.

Seus códigos me ajudam muito e posso economizar muito tempo. Tentei fazer consultas INSERT, SELECT, UPDATE e DELETE com sucesso. Se não estou enganado, o "Cursor" é necessário apenas para a consulta SELECT ??

= pedma




Exatamente, cara!

Os cursores são usados somente para a seleção de dados porque precisamos receber dados do banco de dados em uma variável MQL, e não apenas para enviar o comando sql ao banco de dados.

Fico feliz que minha solução o tenha ajudado.

Boa sorte,

Eugênio

 

Oi Eugênio,

Gostaria de saber se você ainda faz projetos de desenvolvimento pagos, pois estou querendo criar uma copiadora de comércio remoto que seja integrada a um EA que estarei vendendo.

Dei uma olhada no Upwork e parece que você não concluiu nenhum projeto como freelancer recentemente.

Eu mesmo tentei usar a biblioteca que você criou, mas não deu muito certo. Embora eu tenha certeza de que seria fácil para alguém com sua habilidade de programação!

Desde já, obrigado,

James

 
James Beach:

Oi Eugênio,

Gostaria de saber se você ainda faz projetos de desenvolvimento pagos, pois estou querendo criar uma copiadora de comércio remoto que seja integrada a um EA que estarei vendendo.

Dei uma olhada no Upwork e parece que você não concluiu nenhum projeto como freelancer recentemente.

Eu mesmo tentei usar a biblioteca que você criou, mas não deu muito certo. Embora eu tenha certeza de que seria fácil para alguém com sua habilidade de programação!

Desde já, obrigado,

James

Olá, James,

Estou trabalhando no Upwork apenas em um grande projeto no momento. Portanto, não tenho muito tempo livre atualmente. Qual é o problema que você tem com as bibliotecas? Como posso ajudá-lo?