Присоединить MySQL к MQ4 - страница 2

 
с MySql не работал а вот к MS SQL прикручивал
 
как в MQL4 прочитать результат функции mysql_fetch_row ?
 
sergeev:

как в MQL4 прочитать результат функции mysql_fetch_row ?

У меня в данный момент идет разработка скрипта по для работы с базой данный MySQL чтение, вставка, удаление и модификация.

Скрипт объёмный, но суть работы с базой данных будет понятна думаю из одной функции.

Правда в данном примере возвращается ID записи из таблицы, но переделать проблем не составит, помнится я и текст и цифры возвращал из базы, все работало.

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
#import "libmysql.dll"
int mysql_init(int db);
int mysql_errno(int TMYSQL);
int mysql_real_connect(int TMYSQL, string host, string user, string password, string DB,int port,int socket,int clientflag);
int mysql_real_query(int TMSQL, string query, int length);
int mysql_store_result(int TMSQL); 
string mysql_fetch_row(int result); 
int mysql_num_rows(int result); 
void mysql_free_result(int result);
void mysql_close(int TMSQL);
int mysql_insert_id(int result);
#import

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int mysql; string query = ""; int myerr;

int CompanyID = 0;
int SymbolID = 0;
int LastRecordQuotesID = 0;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool connect() { 
   mysql = mysql_init(mysql); 
   if (mysql!=0) Print("allocated"); 
   string host="IP adress";          // меняем на своё
   string user="Login";              // меняем на своё
   string password="Password";       // меняем на своё
   string DB="db_base";              // меняем на своё
   int clientflag=0; 
   int port=3306; 
   string socket=""; 
   int res=mysql_real_connect(mysql,host,user,password,DB,port,socket,clientflag); 
   int err=GetLastError(); 
   if (res==mysql){
      Print("connected"); 
      return(true);
   } else {
      Print("error=",mysql," ",mysql_errno(mysql)," ");
      return(false);
   }
return(false);
} 

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start(){
   if(!connect()) return(0);
//----
   CompanyID = CompanyID(AccountCompany(), AccountServer());
//----
   mysql_close(mysql);
   return(0);
  }

//+--------------------------------------------------------------------------------------------+
//| Функция поиска и вставки названия компании и сервера для связи.                            |
//+--------------------------------------------------------------------------------------------+
//| Переменные:                                                                                |
//|            string AccCompany  - AccountCompany()                                           |
//|            string AccServer   - AccountServer()                                            |
//+--------------------------------------------------------------------------------------------+
int CompanyID(string AccCompany = "", string AccServer = ""){
   int count_records, result;
   string row = "";
   
   query = StringConcatenate("SELECT id FROM Company WHERE Company = \'",AccCompany,"\' AND `Server` = \'",AccServer,"\'");
   mysql_real_query(mysql,query,CountLength(query));
   myerr = mysql_errno(mysql);
   if(myerr > 0) Print("error=",myerr);
   result = mysql_store_result(mysql);
   count_records = Number_Of_Rows(result);
   
   if (count_records > 0){
      row = mysql_fetch_row(result);
      mysql_free_result(result);
      return( StrToInteger(StringSubstr(row, 8, StringLen(row)-1) ) );
   } else {
      query = StringConcatenate( "INSERT INTO `Company` (`Company`, `Server`) VALUES (\'",AccCompany ,"\', \'",AccServer,"\')");
      mysql_real_query(mysql,query,CountLength(query));
      myerr = mysql_errno(mysql);
      if(myerr > 0) Print("CompanyID(): error=",myerr);
      mysql_free_result(result);
      return(mysql_insert_id(mysql));
   }
}

//+--------------------------------------------------------------------------------------------+
//| Вспомогательная Функция подсчёта колличества символов в передаваемом запросе.              |
//+--------------------------------------------------------------------------------------------+
//| Переменные:                                                                                |
//|            string query  - Текстовая страка                                                |
//+--------------------------------------------------------------------------------------------+
int CountLength(string query){
   return(StringLen(query));
}

//+--------------------------------------------------------------------------------------------+
//| Вспомогательная Функция подсчёта колличества результатов из базы данных                    |
//+--------------------------------------------------------------------------------------------+
//| Переменные:                                                                                |
//|            int result  - Результат запроса                                                 |
//+--------------------------------------------------------------------------------------------+
int Number_Of_Rows(int result){
   return(mysql_num_rows(result));
}
 

провёл небольшой следственный эксперимент

создал таблицу с двумя полями
INT id; TEXT user

в таблице две строки
id user
1 aaa
2 bbb

1. При запросе "SELECT id FROM table" функция fetch_row возвращает (адрес)(адрес) 1 (адрес)(адрес) 2
2. При запросе "SELECT user FROM table" функция fetch_row возвращает (адрес)(адрес) aaa (адрес)(адрес) bbb

вобщем то с этим можно работать, жаль только что возврат идёт в string

3. Если запросить два поля "SELECT id, user FROM table" то функция возвращает (адрес)(адрес)(адрес) 1 (адрес)(адрес)(адрес) 2
4. Если поменять местами поля "SELECT user, id FROM table" то функция возвращает (адрес)(адрес)(адрес) aaa (адрес)(адрес)(адрес) bbb

получается, что явно видно только одно первое поле из строки и добавился еще один 4-байтовый адрес.

 
sergeev:

провёл небольшой следственный эксперимент

создал таблицу с двумя полями
INT id; TEXT user

в таблице две строки
id user
1 aaa
2 bbb

1. При запросе "SELECT id FROM table" функция fetch_row возвращает (адрес)(адрес) 1 (адрес)(адрес) 2
2. При запросе "SELECT user FROM table" функция fetch_row возвращает (адрес)(адрес) aaa (адрес)(адрес) bbb

вобщем то с этим можно работать, жаль только что возврат идёт в string

3. Если запросить два поля "SELECT id, user FROM table" то функция возвращает (адрес)(адрес)(адрес) 1 (адрес)(адрес)(адрес) 2
4. Если поменять местами поля "SELECT user, id FROM table" то функция возвращает (адрес)(адрес)(адрес) aaa (адрес)(адрес)(адрес) bbb

получается, что явно видно только одно первое поле из строки и добавился еще один 4-байтовый адрес.


Как же это потом забирать в программу?

Я ведь собираюсь в основном записывать числа с плавающей точкой и читать их. 

 
HIDDEN:

У меня в данный момент идет разработка скрипта по для работы с базой данный MySQL чтение, вставка, удаление и модификация.

Скрипт объёмный, но суть работы с базой данных будет понятна думаю из одной функции.

Правда в данном примере возвращается ID записи из таблицы, но переделать проблем не составит, помнится я и текст и цифры возвращал из базы, все работало.


Это интересный пример, но из него не видно как читать числовые данные.

В принципе, я всего для двух действий хочу использовать базу с таблицей из трёх колонок:

1) Прочитать первые две колонки (индекс и первую числовую колонку)

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

2) Прочитать по индексу этого числа число из второй колонки. 

 

Какие функции для этого мне следует использовать? И нормально ли они работают в указаной DLL? 

 
Eugene1:


Это интересный пример, но из него не видно как читать числовые данные.


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

HIDDEN уже привел полное решение для чтения одного поля из базы. вы его запустили ?

 
Graff:

Если поможете написать конвертер анси в юникод для МКЛ5, код которого приведен в предыдущем посте. Отправлю Вам рабочий код для МКЛ4, так же это поможет при написании класса для МКЛ5.


В MQL5 есть функции для конвертации юникода. Посмотрите /ru/docs/convert/chararraytostring и /ru/docs/convert/stringtochararray

В импорте функций объявляйте не строки, а массивы типа uchar

 
stringo:


В импорте функций объявляйте не строки, а массивы типа uchar


проблема к сожалению в том, что эти строки возвращаются как результат функции, а не в один из её & параметров.

mysql_fetch_row возвращает указатель на массив строк - char**

--------

может кто знает - есть ли какие-то низкоуровневые функции из kernel, которые могут выдать из массива char** - строку char* ?
(типа strcpy, strcat...)

и аналогично из массива int* - какая-то либная функция для получения его конкретного элемента ?
пусть даже сама функция и не предназначена напрямую на эту операцию :)

 

Полная реализация кода....

#import "libmysql.dll"
int mysql_init(int db);
int mysql_errno(int TMYSQL);
int mysql_real_connect(int TMYSQL, string host, string user, string password, string DB,int port,int socket,int clientflag);
int mysql_real_query(int TMSQL, string query, int length);
int mysql_store_result(int TMSQL); 
string mysql_fetch_row(int result); 
int mysql_num_rows(int result); 
void mysql_free_result(int result);
void mysql_close(int TMSQL);
int mysql_insert_id(int result);
#import

#include <WinUser32.mqh>

int mysql; string query = ""; int myerr;
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start(){
   if(!connect()) return(0);
//----
   Print("Возвращаем ID из MySQL: ",Read_ID(10));
   Print("Возвращаем Integer из MySQL: ",Read_Integer(1));
   Print("Возвращаем Double из MySQL: ",DoubleToStr(Read_Double(1),8));
   Print("Возвращаем Datetime из MySQL: ",Read_Datetime(1)," (",StrToTime(Read_Datetime(1)),")");
   Print("Возвращаем Text из MySQL: ",Read_Text(1));
//----
   mysql_close(mysql);
   return(0);
  }
//+------------------------------------------------------------------+
bool connect() { 
   mysql = mysql_init(mysql); 
   if (mysql!=0) Print("allocated"); 
   string host="localhost"; 
   string user="root"; 
   string password=""; 
   string DB="mql4"; 
   int clientflag=0; 
   int port=3306; 
   string socket=""; 
   int res=mysql_real_connect(mysql,host,user,password,DB,port,socket,clientflag); 
   int err=GetLastError(); 
   if (res==mysql){
      Print("connected"); 
      return(true);
   } else {
      Print("error=",mysql," ",mysql_errno(mysql)," ");
      return(false);
   }
return(false);
} 

//+--------------------------------------------------------------------------------------------+
//| Читаем ID из MySQL                                                                         |
//+--------------------------------------------------------------------------------------------+
int Read_ID(int number = 0){
   int count_records, result;
   string row = "";
   
   query = StringConcatenate("SELECT id FROM MQL4_TEST WHERE `integer` = ", number);
   
   mysql_real_query(mysql,query,CountLength(query));
   myerr = mysql_errno(mysql);
   if(myerr > 0) Print("error=",myerr);
   result = mysql_store_result(mysql);
   count_records = Number_Of_Rows(result);
   
   if (count_records > 0){
      row = mysql_fetch_row(result);
      mysql_free_result(result);
      return( StrToInteger(StringSubstr(row, 8, StringLen(row)-1) ) );
   }
}

//+--------------------------------------------------------------------------------------------+
//| Читаем Integer из MySQL                                                                         |
//+--------------------------------------------------------------------------------------------+
int Read_Integer(int id = 0){
   int count_records, result;
   string row = "";
   
   query = StringConcatenate("SELECT `integer` FROM MQL4_TEST WHERE id = ", id);
   mysql_real_query(mysql,query,CountLength(query));
   myerr = mysql_errno(mysql);
   if(myerr > 0) Print("error=",myerr);
   result = mysql_store_result(mysql);
   count_records = Number_Of_Rows(result);
   
   if (count_records > 0){
      row = mysql_fetch_row(result);
      mysql_free_result(result);
      return( StrToInteger(StringSubstr(row, 8, StringLen(row)-1) ) );
   }
}

//+--------------------------------------------------------------------------------------------+
//| Читаем Double из MySQL                                                                         |
//+--------------------------------------------------------------------------------------------+
double Read_Double(int id = 0){
   int count_records, result;
   string row = "";
   
   query = StringConcatenate("SELECT `double` FROM MQL4_TEST WHERE id = ", id);
   mysql_real_query(mysql,query,CountLength(query));
   myerr = mysql_errno(mysql);
   if(myerr > 0) Print("error=",myerr);
   result = mysql_store_result(mysql);
   count_records = Number_Of_Rows(result);
   
   if (count_records > 0){
      row = mysql_fetch_row(result);
      mysql_free_result(result);
      return( StrToDouble(StringSubstr(row, 8, StringLen(row)-1) ) );
   }
}

//+--------------------------------------------------------------------------------------------+
//| Читаем Datetime из MySQL                                                                         |
//+--------------------------------------------------------------------------------------------+
string Read_Datetime(int id = 0){
   int count_records, result;
   string row = "";
   
   query = StringConcatenate("SELECT `datetame` FROM MQL4_TEST WHERE id = ", id);
   mysql_real_query(mysql,query,CountLength(query));
   myerr = mysql_errno(mysql);
   if(myerr > 0) Print("error=",myerr);
   result = mysql_store_result(mysql);
   count_records = Number_Of_Rows(result);
   
   if (count_records > 0){
      row = mysql_fetch_row(result);
      mysql_free_result(result);
      return( StringSubstr(row, 8, StringLen(row)-1) );
   }
}

//+--------------------------------------------------------------------------------------------+
//| Читаем Text из MySQL                                                                         |
//+--------------------------------------------------------------------------------------------+
string Read_Text(int id = 0){
   int count_records, result;
   string row = "";
   
   query = StringConcatenate("SELECT text FROM MQL4_TEST WHERE id = ", id);
   mysql_real_query(mysql,query,CountLength(query));
   myerr = mysql_errno(mysql);
   if(myerr > 0) Print("error=",myerr);
   result = mysql_store_result(mysql);
   count_records = Number_Of_Rows(result);
   
   if (count_records > 0){
      row = mysql_fetch_row(result);
      mysql_free_result(result);
      return( StringSubstr(row, 8, StringLen(row)-1) );
   }
}
//+--------------------------------------------------------------------------------------------+
//| Вспомогательная Функция подсчёта колличества результатов из базы данных                    |
//+--------------------------------------------------------------------------------------------+
//| Переменные:                                                                                |
//|            int result  - Результат запроса                                                 |
//+--------------------------------------------------------------------------------------------+
int Number_Of_Rows(int result){
   return(mysql_num_rows(result));
}

//+--------------------------------------------------------------------------------------------+
//| Вспомогательная Функция подсчёта колличества символов в передаваемом запросе.              |
//+--------------------------------------------------------------------------------------------+
//| Переменные:                                                                                |
//|            string query  - Текстовая страка                                                |
//+--------------------------------------------------------------------------------------------+
int CountLength(string query){
   return(StringLen(query));
}

SQL дамп базы

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `MQL4_TEST`
-- ----------------------------
DROP TABLE IF EXISTS `MQL4_TEST`;
CREATE TABLE `MQL4_TEST` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `integer` int(11) DEFAULT NULL,
  `double` double(11,8) DEFAULT NULL,
  `datetame` datetime DEFAULT NULL,
  `text` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=cp1251;

-- ----------------------------
-- Records of MQL4_TEST
-- ----------------------------
INSERT INTO `MQL4_TEST` VALUES ('1', '10', '20.12345678', '2011-05-16 10:24:43', 'Тестирование MySQL и MQL4');

Результат работы

Причина обращения: