DatabasePrepare

실행할 수 있는 요청 핸들을 DatabaseRead()를 사용하여 생성합니다.

int  DatabasePrepare(
   int     database,      // DatabaseOpen에서 수신된 데이터베이스 핸들
   string  sql,           // SQL 요청
           ...            // 매개변수 요청
   );

매개변수

database

[in] DatabaseOpen()로 수신된 데이터베이스 핸들.

sql

[in]  이름이 지정된 자동 대체 매개변수를 포함할 수 있는 SQL 요청 ?1,?2,...

...

[in]  자동으로 대체되는 요청 매개변수.

반환 값

성공하면 함수는 SQL 요청에 대한 핸들을 반환합니다. 그렇지 않으면 INVALID_HANDLE을 반환합니다. 오류 코드를 가져오려면 GetLastError()를 사용해야 하며, 가능한 응답은 다음과 같습니다:

  • ERR_INVALID_PARAMETER (4003)                  – 데이터베이스 파일의 경로에 빈 문자열이 포함되어 있거나 호환되지 않는 플래그 조합이 설정;
  • ERR_NOT_ENOUGH_MEMORY (4004)              - 충분하지 않은 메모리;
  • ERR_WRONG_STRING_PARAMETER (5040)      – 요청을 UTF-8 문자열로 변환 중에 오류 발생;
  • ERR_DATABASE_INVALID_HANDLE (5121)       - 유효하지 않은 데이터베이스 핸들;
  • ERR_DATABASE_TOO_MANY_OBJECTS (5122) - 허용되는 최대 데이터베이스 개체 수를 초과;
  • ERR_DATABASE_PREPARE (5125)                   - 생성 오류 요청.        

참고

DatabasePrepare() 기능은 데이터베이스에 대한 요청을 수행하지 않습니다. 이 목적은 요청 매개변수를 확인하고 확인 결과에 따라 SQL 요청을 실행하기 위한 핸들을 반환하는 것입니다. 요청 자체는 DatabaseRead()를 처음 호출할 때 설정됩니다.

예:

//--- 거래를 저장할 구조
struct Deal
  {
   ulong             ticket;           // DEAL_TICKET
   long              order_ticket;     // DEAL_ORDER
   long              position_ticket;  // DEAL_POSITION_ID
   datetime          time;             // DEAL_TIME
   char              type;             // DEAL_TYPE
   char              entry;            // DEAL_ENTRY
   string            symbol;           // DEAL_SYMBOL
   double            volume;           // DEAL_VOLUME
   double            price;            // DEAL_PRICE
   double            profit;           // DEAL_PROFIT
   double            swap;             // DEAL_SWAP
   double            commission;       // DEAL_COMMISSION
   long              magic;            // DEAL_MAGIC
   char              reason;           // DEAL_REASON
  };
//--- 거래 저장 구조: 회원의 주문은 터미널 내 포지션에 해당
struct Trade
  {
   datetime          time_in;          // 진입 시간
   ulong             ticket;           // 포지션 ID
   char              type;             // 구매 또는 판매
   double            volume;           // 볼륨
   string            symbol;           // 심볼
   double            price_in;         // 진입 가격
   datetime          time_out;         // 퇴장 시간
   double            price_out;        // 퇴장 가격
   double            commission;       // 진입 및 퇴장 수수료
   double            swap;             // 스왑
   double            profit;           // 수익 또는 손실
  };
//+------------------------------------------------------------------+
//| 스크립트 프로그램 시작 기능                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- 파일 이름 생성
   string filename=IntegerToString(AccountInfoInteger(ACCOUNT_LOGIN))+"_trades.sqlite";
//--- 공용 터미널 폴더에서 데이터베이스 열기/생성
   int db=DatabaseOpen(filenameDATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
   if(db==INVALID_HANDLE)
     {
      Print("DB: "filename" 코드와 함께 열기 실패 "GetLastError());
      return;
     }
//--- DEALS 표를 작성
   if(!CreateTableDeals(db))
     {
      DatabaseClose(db);
      return;
     }
//---  전체 트레이딩 내역을 요청
   datetime from_date=0;
   datetime to_date=TimeCurrent();
//--- 거래 내역을 지정 간격 내에 요청
   HistorySelect(from_dateto_date);
   int deals_total=HistoryDealsTotal();
   PrintFormat("트레이딩 내역 내 거래: %d "deals_total);
//--- 표에 거래 추가
   if(!InsertDeals(db))
      return;
//--- 첫 10개 거래 표시
   Deal deals[], deal;
   ArrayResize(deals10);
   int request=DatabasePrepare(db"SELECT * FROM DEALS");
   if(request==INVALID_HANDLE)
     {
      Print("DB: "filename" 코드를 이용한 요청 실패 "GetLastError());
      DatabaseClose(db);
      return;
     }
   int i;
   for(i=0DatabaseReadBind(requestdeal); i++)
     {
      if(i>=10)
         break;
      deals[i].ticket=deal.ticket;
      deals[i].order_ticket=deal.order_ticket;
      deals[i].position_ticket=deal.position_ticket;
      deals[i].time=deal.time;
      deals[i].type=deal.type;
      deals[i].entry=deal.entry;
      deals[i].symbol=deal.symbol;
      deals[i].volume=deal.volume;
      deals[i].price=deal.price;
      deals[i].profit=deal.profit;
      deals[i].swap=deal.swap;
      deals[i].commission=deal.commission;
      deals[i].magic=deal.magic;
      deals[i].reason=deal.reason;
     }
//--- 거래 출력
   if(i>0)
     {
      ArrayResize(dealsi);
      PrintFormat("첫 %d 거래:"i);
      ArrayPrint(deals);
     }
 
//--- 사용 후 요청 삭제
   DatabaseFinalize(request);
 
//--- 오픈 포지션 관리를 위한 헤징 시스템을 계좌에서 사용하는지 확인
   if((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)!=ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      //--- 거래를 트랜잭션을 통한 단순한 방법을 사용하여 트레이딩으로 전환할 수 없으므로 완전한 운영이 가능합니다
      DatabaseClose(db);
      return;
     }
 
//--- 이제 DEALS 표를 기반으로 TRADES 표를 작성
   if(!CreateTableTrades(db))
     {
      DatabaseClose(db);
      return;
     }
//--- DEALS 표 데이터를 기반으로 SQL 쿼리를 사용하여 TRADES 표를 채우기
   ulong start=GetMicrosecondCount();
   if(DatabaseTableExists(db"DEALS"))
      //--- TRADES 표 덧붙이기
      if(!DatabaseExecute(db"INSERT INTO TRADES(TIME_IN,TICKET,TYPE,VOLUME,SYMBOL,PRICE_IN,TIME_OUT,PRICE_OUT,COMMISSION,SWAP,PROFIT) "
                          "SELECT "
                          "   d1.time as time_in,"
                          "   d1.position_id as ticket,"
                          "   d1.type as type,"
                          "   d1.volume as volume,"
                          "   d1.symbol as symbol,"
                          "   d1.price as price_in,"
                          "   d2.time as time_out,"
                          "   d2.price as price_out,"
                          "   d1.commission+d2.commission as commission,"
                          "   d2.swap as swap,"
                          "   d2.profit as profit "
                          "FROM DEALS d1 "
                          "INNER JOIN DEALS d2 ON d1.position_id=d2.position_id "
                          "WHERE d1.entry=0 AND d2.entry=1     "))
        {
         Print("DB: 코드로 TRADES 표를 채우는데 실패 "GetLastError());
         return;
        }
   ulong transaction_time=GetMicrosecondCount()-start;
   
//--- 첫 10개 거래 표시
   Trade trades[], trade;
   ArrayResize(trades10);
   request=DatabasePrepare(db"SELECT * FROM TRADES");
   if(request==INVALID_HANDLE)
     {
      Print("DB: "filename" 코드를 이용한 요청 실패 "GetLastError());
      DatabaseClose(db);
      return;
     }
   for(i=0DatabaseReadBind(requesttrade); i++)
     {
      if(i>=10)
         break;
      trades[i].time_in=trade.time_in;
      trades[i].ticket=trade.ticket;
      trades[i].type=trade.type;
      trades[i].volume=trade.volume;
      trades[i].symbol=trade.symbol;
      trades[i].price_in=trade.price_in;
      trades[i].time_out=trade.time_out;
      trades[i].price_out=trade.price_out;
      trades[i].commission=trade.commission;
      trades[i].swap=trade.swap;
      trades[i].profit=trade.profit;
     }
//--- 거래 인쇄
   if(i>0)
     {
      ArrayResize(tradesi);
      PrintFormat("\r\nThe first %d trades:"i);
      ArrayPrint(trades);
      PrintFormat("TRADES 표를 채우는 데 %.2f 밀리초가 걸렸습니다",double(transaction_time)/1000);
     }
//--- 사용 후 요청 삭제
   DatabaseFinalize(request);
 
//--- 데이터베이스 닫기
   DatabaseClose(db);
  }
/*
Results:
   Deals in the trading history2741 
   The first 10 deals:
       [ticket] [order_ticket] [position_ticket]              [time] [type] [entry] [symbol] [volume]   [price]   [profit] [swap] [commission] [magic] [reason]
   [034429573              0                 0 2019.09.05 22:39:59      2       0 ""        0.00000   0.00000 2000.00000 0.0000      0.00000       0        0
   [134432127       51447238          51447238 2019.09.06 06:00:03      0       0 "USDCAD"  0.10000   1.32320    0.00000 0.0000     -0.16000     500        3
   [234432128       51447239          51447239 2019.09.06 06:00:03      1       0 "USDCHF"  0.10000   0.98697    0.00000 0.0000     -0.16000     500        3
   [334432450       51447565          51447565 2019.09.06 07:00:00      0       0 "EURUSD"  0.10000   1.10348    0.00000 0.0000     -0.18000     400        3
   [434432456       51447571          51447571 2019.09.06 07:00:00      1       0 "AUDUSD"  0.10000   0.68203    0.00000 0.0000     -0.11000     400        3
   [534432879       51448053          51448053 2019.09.06 08:00:00      1       0 "USDCHF"  0.10000   0.98701    0.00000 0.0000     -0.16000     600        3
   [634432888       51448064          51448064 2019.09.06 08:00:00      0       0 "USDJPY"  0.10000 106.96200    0.00000 0.0000     -0.16000     600        3
   [734435147       51450470          51450470 2019.09.06 10:30:00      1       0 "EURUSD"  0.10000   1.10399    0.00000 0.0000     -0.18000     100        3
   [834435152       51450476          51450476 2019.09.06 10:30:00      0       0 "GBPUSD"  0.10000   1.23038    0.00000 0.0000     -0.20000     100        3
   [934435154       51450479          51450479 2019.09.06 10:30:00      1       0 "EURJPY"  0.10000 118.12000    0.00000 0.0000     -0.18000     200        3
 
   The first 10 trades:
                 [time_in] [ticket] [type] [volume] [symbol] [price_in]          [time_out] [price_out] [commission]   [swap]  [profit]
   [02019.09.06 06:00:03 51447238      0  0.10000 "USDCAD"    1.32320 2019.09.06 18:00:00     1.31761     -0.32000  0.00000 -42.43000
   [12019.09.06 06:00:03 51447239      1  0.10000 "USDCHF"    0.98697 2019.09.06 18:00:00     0.98641     -0.32000  0.00000   5.68000
   [22019.09.06 07:00:00 51447565      0  0.10000 "EURUSD"    1.10348 2019.09.09 03:30:00     1.10217     -0.36000 -1.31000 -13.10000
   [32019.09.06 07:00:00 51447571      1  0.10000 "AUDUSD"    0.68203 2019.09.09 03:30:00     0.68419     -0.22000  0.03000 -21.60000
   [42019.09.06 08:00:00 51448053      1  0.10000 "USDCHF"    0.98701 2019.09.06 18:00:01     0.98640     -0.32000  0.00000   6.18000
   [52019.09.06 08:00:00 51448064      0  0.10000 "USDJPY"  106.96200 2019.09.06 18:00:01   106.77000     -0.32000  0.00000 -17.98000
   [62019.09.06 10:30:00 51450470      1  0.10000 "EURUSD"    1.10399 2019.09.06 14:30:00     1.10242     -0.36000  0.00000  15.70000
   [72019.09.06 10:30:00 51450476      0  0.10000 "GBPUSD"    1.23038 2019.09.06 14:30:00     1.23040     -0.40000  0.00000   0.20000
   [82019.09.06 10:30:00 51450479      1  0.10000 "EURJPY"  118.12000 2019.09.06 14:30:00   117.94100     -0.36000  0.00000  16.73000
   [92019.09.06 10:30:00 51450480      0  0.10000 "GBPJPY"  131.65300 2019.09.06 14:30:01   131.62500     -0.40000  0.00000  -2.62000
   Filling the TRADES table took 12.51 milliseconds
*/  
//+------------------------------------------------------------------+
//| DEALS 표 생성                                          |
//+------------------------------------------------------------------+
bool CreateTableDeals(int database)
  {
//--- DEALS 표가 이미 있는 경우 삭제
   if(!DeleteTable(database"DEALS"))
     {
      return(false);
     }
//--- 표의 존재유무 확인
   if(!DatabaseTableExists(database"DEALS"))
      //--- 표 생성
      if(!DatabaseExecute(database"CREATE TABLE DEALS("
                          "ID          INT KEY NOT NULL,"
                          "ORDER_ID    INT     NOT NULL,"
                          "POSITION_ID INT     NOT NULL,"
                          "TIME        INT     NOT NULL,"
                          "TYPE        INT     NOT NULL,"
                          "ENTRY       INT     NOT NULL,"
                          "SYMBOL      CHAR(10),"
                          "VOLUME      REAL,"
                          "PRICE       REAL,"
                          "PROFIT      REAL,"
                          "SWAP        REAL,"
                          "COMMISSION  REAL,"
                          "MAGIC       INT,"
                          "REASON      INT );"))
        {
         Print("DB: 코드로 DEALS 표를 생성하는데 실패 "GetLastError());
         return(false);
        }
//--- 표가 성공적으로 생성되었습니다
   return(true);
  }
//+------------------------------------------------------------------+
//| 데이터베이스에서 지정된 이름의 표를 삭제        |
//+------------------------------------------------------------------+
bool DeleteTable(int databasestring table_name)
  {
   if(!DatabaseExecute(database"DROP TABLE IF EXISTS "+table_name))
     {
      Print("Failed to drop the DEALS table  with code "GetLastError());
      return(false);
     }
//--- 테이블이 성공적으로 삭제되었습니다
   return(true);
  }
//+------------------------------------------------------------------+
//| 데이터베이스 표에 거래 추가                                 |
//+------------------------------------------------------------------+
bool InsertDeals(int database)
  {
//--- 보조 변수
   ulong    deal_ticket;         // 거래 티켓
   long     order_ticket;        // 거래가 실행된 주문 티켓
   long     position_ticket;     // 거래가 속한 포지션의 ID 
   datetime time;                // 거래 실행 시간
   long     type ;               // 거래 유형
   long     entry ;              // 거래 방향
   string   symbol;              // 거래가 실행된 심볼
   double   volume;              // 작업 볼륨
   double   price;               // 가격
   double   profit;              // 재정적 결과
   double   swap;                // 스왑
   double   commission;          // 수수료
   long     magic;               // 매직 넘버 (엑스퍼트 어드바이저 ID)
   long     reason;              // 거래 실행 이유 또는 소스
//--- 모든 거래를 검토하여 데이터 베이스에 추가
   bool failed=false;
   int deals=HistoryDealsTotal();
// --- 트랜잭션을 실행하기 전에 데이터베이스를 잠금
   DatabaseTransactionBegin(database);
   for(int i=0i<dealsi++)
     {
      deal_ticket=    HistoryDealGetTicket(i);
      order_ticket=   HistoryDealGetInteger(deal_ticketDEAL_ORDER);
      position_ticket=HistoryDealGetInteger(deal_ticketDEAL_POSITION_ID);
      time= (datetime)HistoryDealGetInteger(deal_ticketDEAL_TIME);
      type=           HistoryDealGetInteger(deal_ticketDEAL_TYPE);
      entry=          HistoryDealGetInteger(deal_ticketDEAL_ENTRY);
      symbol=         HistoryDealGetString(deal_ticketDEAL_SYMBOL);
      volume=         HistoryDealGetDouble(deal_ticketDEAL_VOLUME);
      price=          HistoryDealGetDouble(deal_ticketDEAL_PRICE);
      profit=         HistoryDealGetDouble(deal_ticketDEAL_PROFIT);
      swap=           HistoryDealGetDouble(deal_ticketDEAL_SWAP);
      commission=     HistoryDealGetDouble(deal_ticketDEAL_COMMISSION);
      magic=          HistoryDealGetInteger(deal_ticketDEAL_MAGIC);
      reason=         HistoryDealGetInteger(deal_ticketDEAL_REASON);
      //--- 다음 요청에 따라 각 거래를 표에 추가
      string request_text=StringFormat("INSERT INTO DEALS (ID,ORDER_ID,POSITION_ID,TIME,TYPE,ENTRY,SYMBOL,VOLUME,PRICE,PROFIT,SWAP,COMMISSION,MAGIC,REASON)"
                                       "VALUES (%d, %d, %d, %d, %d, %d, '%s', %G, %G, %G, %G, %G, %d, %d)",
                                       deal_ticketorder_ticketposition_tickettimetypeentrysymbolvolumepriceprofitswapcommissionmagicreason);
      if(!DatabaseExecute(databaserequest_text))
        {
         PrintFormat("%s: %d 코드로 #%d 거래 삽입하는데 실패"__FUNCTION__deal_ticketGetLastError());
         PrintFormat("i=%d: 거래 #%d  %s"ideal_ticketsymbol);
         failed=true;
         break;
        }
     }
//--- 트랜잭션 실행 오류를 확인
   if(failed)
     {
      //--- 모든 트랜잭션 롤백 및 데이터베이스 잠금 해제
      DatabaseTransactionRollback(database);
      PrintFormat("%s: %d 코드로 DatabaseExecute() 실패"__FUNCTION__GetLastError());
      return(false);
     }
//--- 모든 트랜잭션이 성공적으로 수행됨 - 변경 사항을 기록하고 데이터베이스 잠금을 해제합니다
   DatabaseTransactionCommit(database);
   return(true);
  }
//+------------------------------------------------------------------+
//| TRADES 표를 생성                                          |
//+------------------------------------------------------------------+
bool CreateTableTrades(int database)
  {
//--- TRADES 표가 이미 있는 경우 삭제
   if(!DeleteTable(database"TRADES"))
      return(false);
//--- 표의 존재유무 확인
   if(!DatabaseTableExists(database"TRADES"))
      //--- 표 생성
      if(!DatabaseExecute(database"CREATE TABLE TRADES("
                          "TIME_IN     INT     NOT NULL,"
                          "TICKET      INT     NOT NULL,"
                          "TYPE        INT     NOT NULL,"
                          "VOLUME      REAL,"
                          "SYMBOL      CHAR(10),"
                          "PRICE_IN    REAL,"
                          "TIME_OUT    INT     NOT NULL,"
                          "PRICE_OUT   REAL,"
                          "COMMISSION  REAL,"
                          "SWAP        REAL,"
                          "PROFIT      REAL);"))
        {
         Print("DB: 코드로 TRADES 표를 생성하는데 실패 "GetLastError());
         return(false);
        }
//--- 표가 성공적으로 생성되었습니다
   return(true);
  }
//+------------------------------------------------------------------+

추가 참조

DatabaseExecute, DatabaseFinalize