DatabaseBind

Define o valor do parâmetro na consulta.

bool  DatabaseBind(
   int  request,      // manipulador da consulta criada em DatabasePrepare
   int  index,        // índice do parâmetro na consulta
   T    value         // valor de parâmetro de tipo simples
   );

Parâmetros

request

[in]  Identificador da consulta criada em DatabasePrepare().

index

[in]  Índice do parâmetro na consulta para o qual é necessário definir o valor. A numeração começa do zero.

value

[in]  Valor do parâmetro que é necessário definir. São permitidos os tipos: bool, char, uchar, short, ushart, int, uint, color, datetime, long, ulong, float, double, string.

Valor retornado

Retorna true em caso de sucesso, caso contrário, false. Para obter o código de erro, use GetLastError(), possíveis respostas:

  • ERR_INVALID_PARAMETER (4003)             — tipo não suportado;
  • ERR_DATABASE_INVALID_HANDLE (5121)  - identificador de banco de dados inválido;
  • ERR_DATABASE_NOT_READY (5128)         - não se pode usar a função para consulta no momento. A consulta está sendo realizada ou já foi concluída, é necessário chamar DatabaseReset().

 

Observação

Esta função deve ser usada caso a consulta SQL contenha os valores parametrizáveis "?" ou"?N", onde N é o número do parâmetro (começando de um). Ao mesmo tempo, a indexação de parâmetros no DatabaseBind() começa do zero.

Por exemplo:

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

Esta função pode ser chamada imediatamente quer após criada a consulta parametrizável em DatabasePrepare() quer após redefinir a consulta para o status inicial com a ajuda do DatabaseReset().

Use esta função juntamente com o DatabaseReset(), para executar a consulta quantas vezes forem necessárias com diferentes valores de parâmetros.

A função é projetada para trabalhar com parâmetros de tipos simples. Se o parâmetro precisar mapear a matriz, use a função DatabaseBindArray().

Exemplo:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   MqlTick ticks[];
//--- lembramo-nos da hora de início antes de receber ticks
   uint start=GetTickCount();
//--- consultamos o histórico de ticks do dia
   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
     {
      //--- quantidade de ticks obtidos em determinado intervalo de tempo
      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)));
     }
 
//--- criamos um nome de arquivo para armazenar o banco de dados
   string filename=_Symbol+" "+TimeToString(datetime(from/1000))+" - "+TimeToString(datetime(to/1000))+".sqlite";
   StringReplace(filename, ":""."); // o caractere ":" não é permitido nos nomes dos arquivos
//--- abrimos/criamos o banco de dados na pasta do terminal compartilhado
   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");
 
//--- criamos a tabela 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;
     }
//--- exibimos uma lista contendo todos os campos na tabela 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;
     }
//--- criamos a consulta parametrizada para adicionar ticks à tabela 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)"// parâmetro de consulta
   int request=DatabasePrepare(db, sql);
   if(request==INVALID_HANDLE)
     {
      PrintFormat("DatabasePrepare() failed with code=%d"GetLastError());
      Print("SQL request: ", sql);
      DatabaseClose(db);
      return;
     }
//--- definimos o valor do primeiro parâmetro da consulta
   DatabaseBind(request, 0, _Symbol);
//--- lembramo-nos da hora de início antes de adicionar ticks à tabela TICKS
   start=GetTickCount();
   DatabaseTransactionBegin(db);
   int total=ArraySize(ticks);
   bool request_error=false;
   for(int i=0; i<total; i++)
     {
      //--- definimos o valor dos restantes parâmetros antes de adicionar um registro
      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;
        }
      //--- se a chamada anterior de DatabaseBind() foi bem-sucedida, definimos o seguinte parâmetro       
      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;
        }
 
      //--- executamos a consulta para inserir o registro e verificamos se há erros
      if(!request_error && !DatabaseRead(request) && (GetLastError()!=ERR_DATABASE_NO_MORE_DATA))
        {
         PrintFormat("DatabaseRead() failed with code=%d"GetLastError());
         DatabaseFinalize(request);
         request_error=true;
         break;
        }
      //--- redefinimos a consulta para seu status inicial antes da seguinte atualização de parâmetros
      if(!request_error && !DatabaseReset(request))
        {
         PrintFormat("DatabaseReset() failed with code=%d"GetLastError());
         DatabaseFinalize(request);
         request_error=true;
         break;
        }
     } //--- acabamos por aqui, passamos por todos os ticks
 
//--- resultado da transação
   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);
     }
 
//--- fechamos o arquivo contendo o banco de dados e relatamos isso
   DatabaseClose(db);
   PrintFormat("Database: %s created and closed", filename);
  }
/*
 Resultado:
  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 
*/

Veja também

DatabasePrepare, DatabaseReset, DatabaseRead, DatabaseBindArray