MQ4へのMySQLのアタッチメント - ページ 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で各フィールドのuchar配列にデータを取り込んでいます。

6. 第 2 項に戻る。

 
HIDDEN:
両方ひねり出しても、4では何も効果がなかった。時には、端末が完全にクラッシュすることもあります。

Kirillさん、MQL4ではすべて動作しています。 ビルド409で テストしました。

以下は、文字列を取得する例です。

#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:

Kirillさん、MQL4ではすべて動作しています。 ビルド409で テストしました。

以下は、文字列を取得する例です。

出来栄え
!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で各フィールドのuchar配列にデータを取り込んでいます。

6.手順2に戻る。



あと少し。この段階では、各行の最初のセルしか取得できない。memcpy はなぜか最初の要素だけを配列にコピーします。一晩を棒に振ってしまった。私は何を間違えているのだろう?

ソース、ダンプ、ログは付録のとおり。

ファイル:
 
Graff:


もう少しだこの段階では、各行の最初のセルしか取得できません。 memcpy はなぜか最初の要素だけを配列にコピーします。一晩を棒に振ってしまった。私は何を間違えているのだろう?

ソースコード、ダンプ、ログは付録。


コメントあり

1.UNICODE2ANSIの関数を使用する必要は全くありません。 このためにCharArrayToStrとShortArrayToStrがあります。

2.strcpy(文字列strDestination, int strSource);関数で文字列を使った試しがない、全て配列でやっていた。UTFエンコーディングからコピーするものがわかっている場合は、短い配列にデータを格納するのがよいでしょう。

3.ここに技術的なエラーがある(だからすべてがうまくいかないのだ)
memcpy(alens,lens,num_fields)とする。

ucharのような 1バイト配列ではないので、memcpy(alens,lens,num_fields*sizeof(int))が必要です。

 
sergeev:

コメントあり

1.UNICODE2ANSI関数を使用する必要は全くありません。 このためにCharArrayToStrとShortArrayToStrがあります。

2.strcpy(文字列strDestination, int strSource);関数で文字列を使った試しがない、全て配列でやっているのですが、どうしたらいいですか?UTFエンコーディングからコピーするものがわかっている場合は、短い配列にデータを格納するのがよいでしょう。

3.ここで技術的なミスが発生する(だから全てがうまくいかなくなる)
memcpy(alens,lens,num_fields)とする。

ucharのような1バイト配列ではないので、memcpy(alens,lens,num_fields*sizeof(int))が必要です。



ありがとうございました。効いてますね。筋肉と連動するクラスやライブラリのリリース予定はありますか?
 
Graff:

ありがとうございました。効いてますね。muslと連携するクラスやライブラリの公開予定はありますか?

必要であれば、説明します。 ただ、すでに明らかになっていることを説明する必要はないのですが...。

このlibmysqlには50個の関数しかない...。

そして、そのほとんどは純粋なサービス機能です。 必要な数十のうち

--------

このクラスやライブラリを実際にどのように考えていますか? どのような機能を持たせるべきでしょうか?

api関数の複製を作ったり、いくつかのアクションを1つの関数にまとめたりすればいいのでは?

 
sergeev:

必要であれば、説明します。 ただ、すでに明らかになっていることを説明する必要はないのですが...。

このlibmysqlには50個の関数しかない...。

そして、そのほとんどは純粋なサービス機能です。 必要な数十のうち

--------

一般的に、このクラスやライブラリをどのように考えていますか? どのような機能を持たせるべきですか?



libmysql.dllの機能を説明するだけでは不十分だと考えています。このクラスは、ユーザーが簡単かつ楽にデータベースを操作できるようにする必要があります。

例1:データベース接続。私のふにゃふにゃしたクラスを経由してデータベースに接続するには、クラスのコンストラクタを 呼び出す必要がありますが、一連の動作はクラスの内部で行われるため、必ずしも知る必要はありませんし、知りたくもありません。

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 へのアクセス違反の読み取りが発生し、システム全体をクラッシュさせることは非常に簡単です。

筋肉に働きかけるオープンクラスを作る可能性を検討する用意がある。