DatabaseBind

リクエストにパラメータ値を設定します。

bool  DatabaseBind(
  int request,     // DatabasePrepareで作成されたリクエストのハンドル
  int index,       // リクエストのパラメータインデックス
  T   value         // 単純型パラメータの値
  );

パラメータ

request

[in] DatabasePrepare()で作成されたリクエストのハンドル。

index

[in] 値を設定する必要があるリクエストのパラメータインデックス(0から始まる)。

value

[in] 設定される値。拡張タイプ: bool、char、uchar、short、ushart、int、uint、color、datetime、long、ulong、float、double、string。

戻り値

成功の場合は true、それ以外の場合は false。エラーコードを受け取るには GetLastError() 関数を使用します。以下の応答が可能です。

  • ERR_INVALID_PARAMETER (4003)             – サポートされていないタイプ
  • ERR_DATABASE_INVALID_HANDLE (5121)  - 無効なデータベースハンドル
  • ERR_DATABASE_NOT_READY (5128)         - 現在、関数を使用してリクエストを行うことはできません。リクエストは実行中か、すでに完了しています。DatabaseReset()が呼び出されるべきです。

 

注意事項

この関数は、SQL要求に「?」または「?N」パラメータ化可能値が含まれている場合に使用されます 。ここで、Nはパラメータインデックス(1から始まる)を意味します。同時に、DatabaseBind()のパラメータインデックスはゼロから開始します。

例は下記の通りです。

    INSERT INTO table VALUES (?,?,?)
    SELECT * FROM table WHERE id=?

この関数は、パラメータ化されたリクエストがDatabasePrepare()で作成された直後、またはリクエストがDatabaseReset()を使用してリセットされた直後に呼び出すことができます。

この関数をDatabaseReset()と一緒に使用して、異なるパラメータ値で必要な回数だけリクエストを実行します。

この関数は、単純型パラメータで動作するように設計されています。パラメータを配列に対して確認する必要がある場合は、DatabaseBindArray()関数を使用します。

例:

//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数                                              |
//+------------------------------------------------------------------+
void OnStart()
 {
  MqlTick ticks[];
//--- ティックを受け取る前に開始時間を覚えておく
  uint start=GetTickCount();
//--- 1日あたりのティック履歴をリクエストする
  ulong to=TimeCurrent()*1000;
  ulong from=to-PeriodSeconds(PERIOD_D1)*1000;
  if(CopyTicksRange(_Symbol, ticks, COPY_TICKS_ALL, from, to)==-1)
    {
    PrintFormat("%s: CopyTicksRange(%s - %s) failed, error=%d",
                _Symbol, TimeToString(datetime(from/1000)), TimeToString(datetime(to/1000)), _LastError);
    return;
    }
  else
    {
    //--- 受信されたティックの数と受信にかかった時間
    PrintFormat("%s: CopyTicksRange received %d ticks in %d ms (from %s to %s)",
                _Symbol, ArraySize(ticks), GetTickCount()-start,
                TimeToString(datetime(from/1000)), TimeToString(datetime(to/1000)));
    }
 
//--- データベースを保存するためのファイル名を設定する
  string filename=_Symbol+" "+TimeToString(datetime(from/1000))+" - "+TimeToString(datetime(to/1000))+".sqlite";
  StringReplace(filename, ":", "."); // ":" 文字はファイル名に使用できない
//--- 共通の端末フォルダーでデータベースを作成または開く
  int db=DatabaseOpen(filename, DATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
  if(db==INVALID_HANDLE)
    {
    Print("Database: ", filename, " open failed with code ", GetLastError());
    return;
    }
  else
    Print("Database: ", filename, " opened successfully");
 
//--- TICKSテーブルを作成する
  if(!DatabaseExecute(db, "CREATE TABLE TICKS("
                      "SYMBOL             CHAR(10),"
                      "TIME               INT NOT NULL,"
                      "BID                REAL,"
                      "ASK                REAL,"
                      "LAST               REAL,"
                      "VOLUME             INT,"
                      "TIME_MSC           INT,"
                      "VOLUME_REAL        REAL);"))
    {
    Print("DB: ", filename, " create table TICKS failed with code ", GetLastError());
    DatabaseClose(db);
    return;
    }
//--- TICKSテーブルのすべてのフィールドのリストを表示する
  if(DatabasePrint(db, "PRAGMA TABLE_INFO(TICKS)", 0)<0)
    {
    PrintFormat("DatabasePrint(\"PRAGMA TABLE_INFO(TICKS)\") failed, error code=%d at line %d", GetLastError(), __LINE__);
    DatabaseClose(db);
    return;
    }
//--- TICKSテーブルにティックを追加するためにパラメータ化されたリクエストを作成する
  string sql="INSERT INTO TICKS (SYMBOL,TIME,BID,ASK,LAST,VOLUME,TIME_MSC,VOLUME_REAL)"
            " VALUES (?1,?2,?3,?4,?5,?6,?7,?8)"; // リクエストパラメータ
  int request=DatabasePrepare(db, sql);
  if(request==INVALID_HANDLE)
    {
    PrintFormat("DatabasePrepare() failed with code=%d", GetLastError());
    Print("SQL request: ", sql);
     DatabaseClose(db);
    return;
    }
//--- 最初のリクエストパラメータの値を設定する
  DatabaseBind(request, 0, _Symbol);
//--- TICKSテーブルにティックを追加する前に開始時間を覚えておく
  start=GetTickCount();
  DatabaseTransactionBegin(db);
  int total=ArraySize(ticks);
  bool request_error=false;
  for(int i=0; i<total; i++)
    {
    //--- エントリを追加する前に残りのパラメータの値を設定する
    ResetLastError();
    if(!DatabaseBind(request, 1, ticks[i].time))
       {
        PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
        PrintFormat("Tick #%d line=%d", i+1, __LINE__);
        request_error=true;
        break;
       }
    //--- い算のDatabaseBind()呼び出しが成功した場合、次のパラメータを設定する
    if(!request_error && !DatabaseBind(request, 2, ticks[i].bid))
       {
        PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
        PrintFormat("Tick #%d line=%d", i+1, __LINE__);
        request_error=true;
        break;
       }
    if(!request_error && !DatabaseBind(request, 3, ticks[i].ask))
       {
        PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
        PrintFormat("Tick #%d line=%d", i+1, __LINE__);
        request_error=true;
        break;
       }
    if(!request_error && !DatabaseBind(request, 4, ticks[i].last))
       {
        PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
        PrintFormat("Tick #%d line=%d", i+1, __LINE__);
        request_error=true;
        break;
       }
    if(!request_error && !DatabaseBind(request, 5, ticks[i].volume))
       {
        PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
        PrintFormat("Tick #%d line=%d", i+1, __LINE__);
        request_error=true;
        break;
       }
    if(!request_error && !DatabaseBind(request, 6, ticks[i].time_msc))
       {
        PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
        PrintFormat("Tick #%d line=%d", i+1, __LINE__);
        request_error=true;
        break;
       }
    if(!request_error && !DatabaseBind(request, 7, ticks[i].volume_real))
       {
        PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
        PrintFormat("Tick #%d line=%d", i+1, __LINE__);
        request_error=true;
        break;
       }
 
    //--- エントリを挿入するリクエストを実行し、エラーを確認する
    if(!request_error && !DatabaseRead(request) && (GetLastError()!=ERR_DATABASE_NO_MORE_DATA))
       {
        PrintFormat("DatabaseRead() failed with code=%d", GetLastError());
        DatabaseFinalize(request);
        request_error=true;
        break;
       }
    //--- 次のパラメータ更新の前にリクエストをリセットする
    if(!request_error && !DatabaseReset(request))
       {
        PrintFormat("DatabaseReset() failed with code=%d", GetLastError());
        DatabaseFinalize(request);
        request_error=true;
        break;
       }
    } //--- すべてのティックの処理が完了した
 
//--- トランザクション状態
  if(request_error)
    {
    PrintFormat("Table TICKS: failed to add %d ticks ", ArraySize(ticks));
    DatabaseTransactionRollback(db);
    DatabaseClose(db);
    return;
    }
  else
    {
    DatabaseTransactionCommit(db);
    PrintFormat("Table TICKS: added %d ticks in %d ms",
                ArraySize(ticks), GetTickCount()-start);
    }
 
//--- データベースファイルを閉じて、その件を通知する
  DatabaseClose(db);
  PrintFormat("Database: %s created and closed", filename);
 }
/*
 結果:
 EURUSD: CopyTicksRange received 268061 ticks in 47 ms (from 2020.03.18 12:40 to 2020.03.19 12:40)
 Database: EURUSD 2020.03.18 12.40 - 2020.03.19 12.40.sqlite opened successfully
 #| cid name        type     notnull dflt_value pk
 -+-----------------------------------------------
 1|   0 SYMBOL      CHAR(10)       0             0
 2|   1 TIME        INT            1             0
 3|   2 BID         REAL           0             0
 4|   3 ASK         REAL           0             0
 5|   4 LAST        REAL           0             0
 6|   5 VOLUME      INT            0             0
 7|   6 TIME_MSC    INT            0             0
 8|   7 VOLUME_REAL REAL           0             0
 Table TICKS: added 268061 ticks in 797 ms
 Database: EURUSD 2020.03.18 12.40 - 2020.03.19 12.40.sqlite created and closed
 OnCalculateCorrelation=0.87 2020.03.19 13:00:  EURUSD vs GBPUSD  PERIOD_M30
*/

参照

DatabasePrepareDatabaseResetDatabaseReadDatabaseBindArray