Attacher MySQL à MQ4 - page 5

 
sergeev:

Oui, tout fonctionne parfaitement, mais pour l'instant je ne l'ai fait que pour MQL5

un exemple de fonctionnement de mon post ci-dessus


Pouvez-vous m'envoyer un morceau de code concernant mysql_fetch_row, votre exemple ne montre pas clairement comment récupérer les cellules lorsque le résultat est composé de plusieurs lignes et colonnes.
 
Graff:

Pouvez-vous envoyer un morceau de code concernant mysql_fetch_row, il n'est pas clair dans votre exemple comment obtenir des cellules lorsque le résultat est composé de plusieurs lignes et colonnes.

de la même manière.

1. prendre mysql_num_rows, mysql_num_fields

2. obtenir un pointeur vers un tableau de pointeurs vers la chaîne suivante mysql_fetch_row, et un pointeur vers les longueurs des champs mysql_fetch_lengths

3. nous tirons ces longueurs du tableau des longueurs dans notre propre tableau (via memcpy).

4. à partir d'un pointeur sur un tableau de pointeurs de champs, tirer ce tableau de pointeurs de champs (puisque nous connaissons mysql_num_fields).

5. Connaissant les longueurs des champs (tableau de longueurs obtenu par fetch_lengths) et les pointeurs vers les champs eux-mêmes, nous tirons les données dans le tableau uchar de chaque champ avec memcpy.

6. revenir à la clause 2.

 
HIDDEN:
Je l'ai tourné et retourné dans tous les sens, rien n'a marché pour moi sur le 4. Il arrive même que le terminal se plante complètement.

Kirill, tout fonctionne dans MQL4. Je l'ai testé sur la build 409 .

Voici un exemple pour obtenir une chaîne de caractères

#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); // вывели на печать
}

résultat
!sql USDCHF,M30 : client_info=6.0.0

de même pour un tableau d'entiers
remplacer par

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

Kirill, tout fonctionne dans MQL4. Je l'ai testé sur la build 409 .

Voici un exemple pour obtenir la chaîne de caractères

résultat
!sql USDCHF,M30 : client_info=6.0.0

la même chose si vous le faites pour un tableau
remplacer par

J'ai le même build, mais mon terminal plante.... Je dois l'essayer sur différents terminaux de différentes sociétés de courtage.

Bien que cela puisse dépendre du système, je teste avec win7 x64.

 

HIDDEN:


xp/32

Trouvez ensuite les différentes options d'appel et contactez le Service Desk au sujet du bug.

Peut-être qu'ils vous conseilleront sur ce qu'il faut faire.

 
sergeev:

de la même manière.

1. prendre mysql_num_rows, mysql_num_fields

2. obtenir un pointeur vers un tableau de pointeurs vers la chaîne suivante mysql_fetch_row, et un pointeur vers les longueurs des champs mysql_fetch_lengths

3. nous tirons ces longueurs du tableau des longueurs dans notre propre tableau (via memcpy).

4. à partir d'un pointeur vers un tableau de pointeurs de champs, tirer ce tableau de pointeurs de champs (puisque nous connaissons mysql_num_fields).

5. Connaissant les longueurs des champs (tableau de longueurs obtenu par fetch_lengths) et les pointeurs vers les champs eux-mêmes, nous tirons les données dans le tableau uchar de chaque champ avec memcpy.

6. retour à l'étape 2.



On y est presque. À ce stade, nous ne pouvons obtenir que la première cellule de chaque ligne. memcpy pour une raison quelconque ne copie que le premier élément dans mes tableaux. Ça a tué une soirée entière. Qu'est-ce que je fais de mal ?

Source, décharge, journal en annexe.

Dossiers :
 
Graff:


Je l'ai presque. À ce stade, je ne peux obtenir que la première cellule de chaque ligne. memcpy ne copie que le premier élément dans mes tableaux pour une raison quelconque. Ça a tué une soirée entière. Qu'est-ce que je fais de mal ?

Code source, dump, log en annexe.


il y a des commentaires

1) Il n'est pas du tout nécessaire d'utiliser les fonctions UNICODE2ANSI. Vous disposez de CharArrayToStr et ShortArrayToStr à cet effet.

2. je n'ai pas essayé d'utiliser une chaîne dans la fonction strcpy(string strDestination, int strSource) ;, tout a été fait à travers des tableaux. Si vous savez ce que vous copiez à partir du codage UTF, il est préférable de stocker les données dans un tableau court.

3. vous avez ici une erreur technique (c'est pourquoi tout va mal)
memcpy(alens,lens,num_fields) ;

Ce n'est pas un tableau à un seul octet comme uchar. J'ai besoin de memcpy(alens,lens,num_fields*sizeof(int)) ;

 
sergeev:

il y a des commentaires

1) Il n'est pas du tout nécessaire d'utiliser les fonctions UNICODE2ANSI. Vous disposez de CharArrayToStr et ShortArrayToStr à cet effet.

2. je n'ai pas essayé d'utiliser une chaîne de caractères dans la fonction strcpy(string strDestination, int strSource) ;, tout est fait à travers des tableaux. Si vous savez ce que vous copiez à partir du codage UTF, il est préférable de stocker les données dans un tableau court.

3. C'est là que vous avez une erreur technique (qui fait que tout va mal).
memcpy(alens,lens,num_fields) ;

ce n'est pas un tableau à un seul octet comme uchar. vous avez besoin de memcpy(alens,lens,num_fields*sizeof(int)) ;



Merci ! Ça marche. Est-il prévu de publier une classe ou une bibliothèque pour travailler avec le muscle ?
 
Graff:

Merci ! Ça marche. Est-il prévu de publier une classe ou une bibliothèque permettant de travailler avec musl ?

S'il y a un besoin, je peux. Mais je n'ai pas besoin d'expliquer ce qui est déjà clair...

Il n'y a que 50 fonctions dans cette libmysql...

et la plupart d'entre eux sont des fonctions purement de service. Sur les dizaines dont vous avez besoin.

--------

Comment voyez-vous cette classe ou cette bibliothèque ? Quelles fonctions devrait-elle avoir ?

Il suffit de dupliquer les fonctions de l'API, ou de regrouper certains ensembles d'actions dans une seule fonction ?

 
sergeev:

S'il y a un besoin, je peux. Mais je n'ai pas besoin d'expliquer ce qui est déjà clair...

Il n'y a que 50 fonctions dans cette libmysql...

la plupart d'entre elles sont des fonctions purement de service. dix d'entre elles sont essentielles au travail.

--------

En général, comment voyez-vous cette classe ou cette bibliothèque ? Quelles fonctions devrait-elle avoir ?



Je pense que la simple description des fonctions de libmysql.dll n'est pas suffisante. La classe doit permettre à l'utilisateur de travailler avec la base de données de manière simple et sans effort.

Exemple 1 : Connexion à la base de données. Pour se connecter à la base de données via ma faible classe, le constructeur de la classe doit être appelé, bien que toute une série d'actions, pas toujours nécessaires ou même requises, aient lieu à l'intérieur de la classe.

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

Exemple 2 : obtenir un résultat multi-lignes et multi-colonnes. Tout ce dont l'utilisateur a besoin est de fournir la requête et un tableau (structure) pour écrire le résultat.

//+------------------------------------------------------------------+
//|  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);
  }

^ il s'agit d'un vieux code, juste pour avoir une idée.

Il peut également y avoir de nombreux exemples sur la façon d'ajouter des informations à la base de données.

Si vous n'utilisez qu'un ensemble de fonctions sans contrôle, il est très facile d'obtenir une violation d'accès en lecture à 0x00000000 dans 'libmysql.dll' et de faire planter tout le système.

Prêt à envisager la possibilité de créer une classe ouverte pour travailler avec le muscle.

Raison: