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()中的参数索引从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",

                  _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, ":", "."); // ":" 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