Скачать MetaTrader 5

Вопрос по mysql и metatrader5

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Поиск в документации доступен через MetaTrader 5. Ищи и изучай!
j0hndoe
13
j0hndoe 2016.11.20 13:06 

Здравствуйте.

Прочитал статью  ИЗБАВЛЯЕМСЯ ОТ БАЛЛАСТА САМОДЕЛЬНЫХ DLL

и ветку на форуме Присоединить MySQL к MQ4

У меня не получается сделать вывод данных из базы.

Первое поле выводится нормально, а затем пустые строки через одну.

Подскажите где ошибка у меня, а то уже неделю не получается (

#import "libmysql.dll"
  int mysql_init(int mysql);
  int mysql_real_connect(int mysql, uchar &host[], uchar &user[], uchar &password[],
                            uchar &DB[], uint port, uchar &socket[], int clientflag);
  int mysql_get_client_info();
  int mysql_get_host_info(int mysql);
  int mysql_get_server_info(int mysql);
  int mysql_character_set_name(int mysql);
  int mysql_stat(int mysql);
  
    int mysql_real_query(int mysql, uchar &query[], int length);
  int mysql_store_result(int mysql);
  int mysql_field_count(int mysql);
  uint mysql_num_rows(int result);
  int mysql_num_fields(int result);
  int mysql_fetch_lengths(int result);
  int mysql_fetch_row(int result);
  void mysql_close(int TMSQL);
#import "msvcrt.dll"
  int strcpy(uchar &dst[], int src);


int memcpy(uchar &Destination[],uchar &Source[],int Length);
int memcpy(uchar &Destination[],int Source,int Length);
int memcpy(uchar &Destination[],uchar &Source[],int Length);
int memcpy(int &Destination[],int Source,int Length);  

/*
//int memcpy(uchar &Destination[],uchar &Source[],int Length);// отвечает за
int memcpy(uchar &Destination[],int Source,int Length);     // memcpy(byte, field_ptr[f], lens[f]);
//int memcpy(uchar Destination,int &Source[],int Length);     //отвечает за
int memcpy(int &Destination[],int Source,int Length);       // первые 2 memcpy
*/




#import
int port=3306;
string st;


int mysql=mysql_init(st);
int deinit()
{
mysql_close(mysql);
//----
return(0);
}

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
  uchar byte[];
  ArrayResize(byte, 0);

  int ptr;
//  string st;
  //--- указатель на строку
  ptr=mysql_get_client_info();



  //--- переводим строки в байтовые массивы
  uchar ahost[];
  StringToCharArray("localhost", ahost);
  uchar auser[];
  StringToCharArray("root", auser);
  uchar apwd[];
  StringToCharArray("", apwd);
  uchar adb[];
  StringToCharArray("fx", adb);
  uchar asocket[];
  StringToCharArray("", asocket);
  //--- соединяемся с базой
  int rez=mysql_real_connect(mysql, ahost, auser, apwd, adb, port, asocket, 0);
  //--- узнаем состояние соединения и базы
/*
  ptr=mysql_get_host_info(mysql);
  if (ptr>0) strcpy(byte, ptr);
  Print("mysql_host_info="+CharArrayToString(byte));
  ptr=mysql_get_server_info(mysql);
  if (ptr>0) strcpy(byte, ptr);
  Print("mysql_server_info="+CharArrayToString(byte));
  ptr=mysql_character_set_name(mysql);
  if (ptr>0) strcpy(byte, ptr);
  Print("mysql_character_set_name="+CharArrayToString(byte));
  ptr=mysql_stat(mysql);
  if (ptr>0) strcpy(byte, ptr);
  Print("mysql_stat="+CharArrayToString(byte));
*/

//====================================================
//--- ... предварительно проинициализированная база данных mysql
  //--- запрос на получение всех строк из таблицы table
  string query="SELECT user,password,host,file_priv FROM mysql.user limit 2,3;";
//string query="select date_buff,iACBuffer,iADBuffer,ADXBuffer,MiddleBuffer,UpperBuffer,LowerBuffer from usdjpy_h1 limit 0,1;";
//string query="select * from usdjpy_h1 limit 0,3;";
//  string query="SELECT * FROM mysql.user;";
  uchar aquery[];
  StringToCharArray(query, aquery);

  //--- отправляем запрос
  int err=mysql_real_query(mysql, aquery, StringLen(query));
  int result=mysql_store_result(mysql);

  //--- если содержит строки
  if (result>0)
  {
    ulong num_rows=mysql_num_rows(result);
    int num_fields=mysql_num_fields(result);    
   //   Print("Строк- ", num_rows, " Полей- ", num_fields);
    //--- получим указатель первую строку
    int r=0, row_ptr=mysql_fetch_row(result);
    while(row_ptr>0)
    {
    Print("====================String N", r+1 ,"====================");
       //--- получим указатель на длины столбцов текущей строки
      int len_ptr=mysql_fetch_lengths(result);
      int lens[];
       ArrayResize(lens, num_fields);
      //--- получим размеры полей строки
      memcpy(lens, len_ptr, num_fields*sizeof(int));
      //--- получаем поля данных  
      int field_ptr[];
      ArrayResize(field_ptr, num_fields);
      ArrayInitialize(field_ptr, 0);

      //--- получим указатели на поля
      memcpy(field_ptr, row_ptr, num_fields*sizeof(int));
      for (int f=0; f<num_fields; f++)
      {
        ArrayResize(byte, lens[f]);
        ArrayInitialize(byte, 0);
        
         //--- скопируем поле в байтовый массив byte
        if (field_ptr[f]>0 && lens[f]>0)    memcpy(byte, field_ptr[f], lens[f]);
       Print(" поле: ",f+1," ",CharArrayToString(byte)," field_ptr: ",field_ptr[f]," lens: ",lens[f]);

       }
      
      r++;
      //--- получим указатель на указатель на следующую строку
      row_ptr=mysql_fetch_row(result);
    }
  }
}
Избавляемся от балласта самодельных DLL
Избавляемся от балласта самодельных DLL
  • 2012.01.31
  • o_O
  • www.mql5.com
Если MQL5-программисту недостаточно функционала языка, он вынужден обращаться к дополнительным инструментам. Для этого приходится использовать другой язык программирования и создавать промежуточную DLL. В MQL5 имеется механизм представления разных типов данных с помощью структур и передачи их в API, но к сожалению, MQL5 не отвечает нам на вопрос о том, как вытянуть данные из принятого указателя. В данной статье мы поставим точку в этом вопросе и покажем простые механизмы обмена сложными типами данных и работе с ними.
o_o
Модератор
23695
o_o 2016.11.21 21:27  

ответил вам в личку, но продублиру здесь,
----
у вашего примера  LIMIT 0,2

это получается вы сами ограничили его двумя строками 0 и 2

может поэтому?

----

во-вторых примите рекомендации, важно следовать им.

1- во всех запросах в sql экранировать имена полей и таблиц.  SELECT `Id`, `Name`, `Price` FROM `cars`
2- если у вас 64 битная версия - то важно!!!  обратите внимание что вовзращает sql.  Он чаще всего возвращает указатели. А в 64 битной системе это же long, а не int.  (только не спутайте long в с++.  Он в нём 4 байтное обычный int)
И это нужно исправить во всех api функциях и winapi тоже.

пример

#import "libmysql.dll"
        long mysql_init(long mysql);
        long mysql_real_connect(long mysql, uchar &host[], uchar &user[], uchar &password[], uchar &DB[], uint port, uchar &socket[], int clientflag);
        long mysql_get_client_info();
        long mysql_get_host_info(long mysql);
        long mysql_get_server_info(long mysql);
        long mysql_character_set_name(long mysql);
        long mysql_stat(long mysql);
        
        int mysql_real_query(long mysql, uchar &query[], int length);
        long mysql_store_result(long mysql);
        int mysql_field_count(long mysql);
        ulong mysql_num_rows(long result);
        int mysql_num_fields(long result);
        ulong mysql_fetch_lengths(long result);
        long mysql_fetch_row(long result);
        void mysql_close(long TMSQL);
#import "msvcrt.dll"
  long strcpy(uchar &dst[], long src);
  long memcpy(uchar &Destination[],long Source,int Length);
  long memcpy(long &Destination[],long Source,int Length);
  int memcpy(int &Destination[],int Source,int Length);
#import
o_o
Модератор
23695
o_o 2016.11.21 21:30  

ваш исправленный скрипт в приложении

вот что он выдаёт (всё верно) из тестовой БД

без никаких пропусков и верной возвращаемой длиной полей




сама таблица имеет соответственный вид


Файлы:
j0hndoe
13
j0hndoe 2016.11.21 21:44  

Спасибо Вам,

Вы мне очень помогли )

o_o
Модератор
23695
o_o 2016.11.21 21:59  
дело оказалось таки в LIMIT 0,2 ? )
j0hndoe
13
j0hndoe 2016.11.22 20:51  
o_O:
дело оказалось таки в LIMIT 0,2 ? )

Если бы )

Все дело было в том что у меня win7_64, а при прочтении темы я это проигнорировал.

Очень невнимательный читатель.

Подумал что если выдает строки через одну - значит я допустил ошибку в memcpy,

но никак ни в типах данных.

int, только long

рабочий mysql_api12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий