将MySQL连接到MQ4 - 页 5

 
sergeev:

是的,一切工作都很完美,但到目前为止,我只为MQL5制作了它。

在我的帖子中,有一个例子说明了它是如何工作的。


你能不能给我发一段关于mysql_fetch_row的代码,从你的例子中不清楚当结果由几行和几列组成时如何获取单元。
 
Graff:

你能不能发送一段关于mysql_fetch_row的代码,从你的例子中不清楚当结果由几行和几列组成时如何获得单元格。

类似地。

1.取mysql_num_rows, mysql_num_fields

2.获得一个 指向下一个字符串的数组的指针 mysql_fetch_row,以及一个指向字段长度的指针 mysql_fetch_lengths

3.我们把这些长度从lengths数组拉到我们自己的数组中(通过memcpy)。

4.从一个指向字段指针的数组,拉出这个字段指针数组(因为我们知道mysql_num_fields)。

5.知道了字段的长度(从fetch_lengths得到的长度数组)和字段本身的指针,我们用memcpy把数据拉到每个字段的ucar数组中。

6. 回到第2条。

 
HIDDEN:
我已经把它扭曲了,对我来说,4号机没有任何作用。有时终端甚至完全崩溃。

基里尔,在MQL4中一切正常。 我在Build409 上测试了它。

下面是一个获取字符串的例子

#import "libmysql.dll"
    int mysql_get_client_info(); // функция вернула char*
#import "msvcrt.dll"
    int strcpy(string strDestination, int strSource); // копируем NULL-строку из source в байтовый массив 
#import

void start()
{
    int ptr; string data="123456789"; 
    ptr=mysql_get_client_info(); // получили указатель на строку
    strcpy(data, ptr); // скопировали его в массив
    Print("client_info="+data); // вывели на печать
}

结果
!sql USDCHF,M30:client_info=6.0.0

对整数阵列也是如此
换成

    int strcpy(int &strDestination[], int strSource); // копируем NULL-строку из source в байтовый массив 
 
sergeev:

基里尔,在MQL4中一切正常。 我在Build409 上测试了它。

下面是一个获取字符串的例子

结果
!sql USDCHF,M30:client_info=6.0.0

如果你对一个数组做同样的事情
换成

我有相同的构建,但我的终端崩溃了....我必须在不同经纪公司的不同终端上进行尝试。

虽然这可能取决于系统,但我是用win7 x64测试的。

 

HIDDEN:


xp/32

然后四处挖掘电话,并直接联系服务台了解该错误。

也许他们会建议该怎么做。

 
sergeev:

类似地。

1.取mysql_num_rows, mysql_num_fields

2.获得一个指向下一个字符串的数组的指针 mysql_fetch_row,以及一个指向字段长度的指针 mysql_fetch_lengths

3.我们把这些长度从lengths数组拉到我们自己的数组中(通过memcpy)。

4.从一个指向字段指针的数组,拉出这个字段指针数组(因为我们知道mysql_num_fields)。

5.知道了字段的长度(从fetch_lengths得到的长度数组)和字段本身的指针,我们用memcpy把数据拉到每个字段的ucar数组中。

6.回到第2步。



快到了。在这个阶段,我们只能得到每行的第一个单元格。由于某些原因,memcpy 只复制第一个元素到我的数组中。杀了一整个晚上。我做错了什么?

来源,转储,附录中的日志。

附加的文件:
 
Graff:


几乎得到了它。在这个阶段,我只能得到每行的第一个单元格。 由于某种原因,memcpy只把第一个元素复制到我的数组中。杀了一整个晚上。我做错了什么?

源代码,转储,附录中的日志。


有评论

1.根本不需要使用UNICODE2ANSI函数。 你有CharArrayToStr和ShortArrayToStr用于此目的。

2.我没有尝试在strcpy(string strDestination, int strSource);函数中使用字符串,一切都通过数组完成。如果你知道你要从UTF编码中复制什么,最好将数据存储在一个短数组中。

3.这里你有一个技术错误(这就是为什么一切都会出错)。
memcpy(alens,lens,num_fields)。

我需要memcpy(alens,lens,num_fields*sizeof(int)),它不是像ucar那样的 单字节数组。

 
sergeev:

有评论

1.根本不需要使用UNICODE2ANSI函数。 你有CharArrayToStr和ShortArrayToStr用于此目的。

2.我没有尝试在strcpy(string strDestination, int strSource);函数中使用字符串,一切都通过数组完成。如果你知道你要从UTF编码中复制什么,最好将数据存储在一个短数组中。

3.这就是你的技术错误(这就是一切出错的原因)。
memcpy(alens,lens,num_fields)。

它不是像ucar那样的单字节数组。你需要memcpy(alens,lens,num_fields*sizeof(int))。



谢谢你!它正在发挥作用。有没有计划发布一个类或库来与肌肉合作?
 
Graff:

谢谢你!它正在发挥作用。有没有计划发布一个与Musl一起工作的类或库?

如果有需要,我可以。 我只是不需要解释已经很清楚的事情...

这个libmysql中只有50个函数...

而其中大部分是纯粹的服务功能。 在你所需要的几十个中。

--------

你究竟如何看待这个类或库? 它应该有哪些功能?

只是让api函数重复,或者把一些动作集放到一个函数中?

 
sergeev:

如果有需要,我可以。 我只是不需要解释已经很清楚的事情...

这个libmysql中只有50个函数...

其中大部分是纯粹的服务功能。其中有10个是工作所必需的。

--------

一般来说,你如何看待这个类或库? 它应该有哪些功能?



我认为,仅仅描述libmysql.dll的功能是不够的。该类必须允许用户简单而毫不费力地与数据库一起工作。

例1:DB连接。为了通过我的软体类连接到数据库,必须调用该类的构造函数,尽管在该类中发生了一系列的动作,但你并不总是需要和想要知道这些。

CMYSQL2::CMYSQL2(const string host="localhost",const string user="root",const string password="",const string database="database",const uint port=3306)
  {
   uchar _host[],_user[],_password[],_database[],_socket[];
   StringToCharArray(host,_host);
   StringToCharArray(user,_user);
   StringToCharArray(password,_password);
   StringToCharArray(database,_database);
// Connecting
   mysql=mysql_init(NULL);
   uint conn=mysql_real_connect(mysql,_host,_user,_password,_database,port,_socket,0);
   if(mysql==NULL || conn==NULL || mysql!=conn){ Print(__FUNCTION__,"-> MySQL connetion failure.");}
  }

例2:得到一个多行多列的结果。用户只需要输入查询和一个数组(结构)来写入结果。

//+------------------------------------------------------------------+
//|  Returns string array as sql_results struct param and rows count
//+------------------------------------------------------------------+
uint CMYSQL2::GetArray(string query,sql_results &out[])
  {
   Query2(query);
   StoreResult();
   uint rows=GetNumRows();
   uint fields=GetNumFields();
   ArrayResize(out,rows);

   for(uint r=0;r<rows;r++)
     {
      ArrayResize(out[r].value,fields);
      string fr_res=mysql_fetch_row(result);
      
      for(uint f=0;f<fields;f++)
        {
         out[r].value[f]=get_cell_u(fr_res,f);//Print("3,",f,",",fields);
        }
     }
   FreeLastResult();
   return(rows);
  }

^ 这是旧代码,只是为了了解情况。

也可以有很多关于如何向数据库添加信息的例子。

如果你只是使用一组没有检查的函数,很容易在'libmysql.dll'中获得对0x00000000的访问违规读取并使整个系统崩溃。

准备考虑创建一个公开课的可能性,以便与肌肉一起工作。