DatabaseBind

Устанавливает значение параметра в запросе.

bool  DatabaseBind(
   int  request,      // хендл запроса, созданного в DatabasePrepare
   int  index,        // индекс параметра в запросе
   T    value         // значение параметра простого типа
   );

Параметры

request

[in]  Хендл запроса, созданного в DatabasePrepare().

index

[in]  Индекс параметра в запросе, для которого нужно установить значение. Нумерация начинается с нуля.

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 означает номер параметра (начиная с единицы). При этом индексация параметров в DatabaseBind() начинается с нуля.

Например:

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

Функцию можно вызывать сразу после того, как параметризованный запрос был создан в DatabasePrepare(), либо после сброса запроса в начальное состояние с помощью DatabaseReset().

Используйте эту функцию совместно с DatabaseReset(), чтобы выполнить запрос нужное количество раз с разными значениями параметров.

Функция предназначена для работы с параметрами простых типов. Если параметру требуется сопоставить массив, используйте функцию DatabaseBindArray().

Пример:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
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, ":""."); // символ ":" запрещен в названиях файлов
//--- открываем/создаем базу данных в общей папке терминалов
   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 
*/

Смотри также

DatabasePrepare, DatabaseReset, DatabaseRead, DatabaseBindArray