DatabaseBind

在请求中设置一个参数值。

bool  DatabaseBind(
   int  request,      // DatabasePrepare中创建的请求句柄
   int  index,        // 请求中的参数索引
   T    value         // 简单类型参数的值
   );

参数

request

[in] DatabasePrepare()中创建的请求句柄。

index

[in]  应该为请求中的参数索引设置一个值。编号从0开始。

[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()中的参数索引从0开始。

例如:

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

该函数可以在DatabasePrepare()中创建参数化请求或使用DatabaseReset()重置请求之后立即调用。

将该函数与DatabaseReset()一起使用,可以根据需要使用不同的参数值来多次执行请求。

该函数旨在使用简单的类型参数。如果应对数组检查参数,请使用DatabaseBindArray()函数。

例如:

//+------------------------------------------------------------------+
//| 脚本程序起始函数                                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
   MqlTick ticks[];
//--- 记住收到报价的开始时间
   uint start=GetTickCount();
//--- 请求每日报价历史
   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",
                  _SymbolTimeToString(datetime(from/1000)), TimeToString(datetime(to/1000)), _LastError);
      return;
     }
   else
     {
      //--- 接收多少报价,以及接收报价所花费的时间
      PrintFormat("%s: CopyTicksRange received %d ticks in %d ms (from %s to %s)",
                  _SymbolArraySize(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, ":""."); // ":" character is not allowed in file names
//--- 在常规程序端文件夹中打开/创建数据库
   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)"// request parameters
   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