Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 1869

 

Уже пару часов бьюсь над попыткой прочитать из БД данные и не могу этого сделать.

Вот код-советника для тестов.

Кратко. Создается БД с одной табличкой (если БД существует - таблица удаляется и создается заново). В таблицу добавляется одна единственная строка.

Далее БД закрывается и открывается снова. Делается простой селект этой записи, но команда возвращает ошибку, что результат запроса пустой.

Проверил через IDE - все выбирается по этому же самому запросу. Не могу понять, это баг или фича?

int OnInit()
{
//---
   int db_handle = DatabaseOpen("test3", DATABASE_OPEN_COMMON | DATABASE_OPEN_CREATE | DATABASE_OPEN_READWRITE);
   if (db_handle != INVALID_HANDLE)
      {
         // Структура таблицы
         if (DatabaseTableExists(db_handle, "ea_dsc"))
            if(!DatabaseExecute(db_handle, "DROP TABLE IF EXISTS ea_dsc"))
               Print("Failed to drop table with code ", GetLastError());

         string t_create = "CREATE TABLE ea_dsc (dsc_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "
                           " ea_symb TEXT NOT NULL, dt_from TEXT NOT NULL, dt_to TEXT, magic_buy INTEGER NOT NULL, "
                           " magic_sell INTEGER NOT NULL, version TEXT NOT NULL, ea_method TEXT NOT NULL)";
         if(!DatabaseExecute(db_handle, t_create))
            Print("Failed to create table with code ", GetLastError());

         string t_add = "INSERT INTO ea_dsc (ea_symb, dt_from, dt_to, magic_buy, magic_sell, version, ea_method)"
                        "VALUES ('EURUSD', 'dt_from', NULL, '123', '456', 'version', 'ea_method')";

         if(!DatabaseExecute(db_handle, t_add))
            Print("Failed to add table data  with code ", GetLastError());

         DatabaseClose(db_handle);
      }

   db_handle = DatabaseOpen("test3", DATABASE_OPEN_COMMON | DATABASE_OPEN_READWRITE);
   if (db_handle != INVALID_HANDLE)
      {
         // Запрос
         string s_quer = "SELECT dsc_id, ea_symb, dt_from, dt_to, magic_buy,"
                         "magic_sell, version, ea_method FROM ea_dsc WHERE ea_symb = ?1";
         int c_request = DatabasePrepare(db_handle, s_quer);
         if (c_request != INVALID_HANDLE)
            {
               if (DatabaseBind(c_request, 0, "EURUSD"))
                  if (DatabaseRead(c_request))
                     {
                        Print("Found!");
                     }
                  else
                     PrintFormat("Error=%d", GetLastError());
               DatabaseFinalize(c_request);
            }
         DatabaseClose(db_handle);
      }

//---
   return(INIT_SUCCEEDED);
}

Результат работы:

 PrintFormat("Error=%d", GetLastError());

Также, полный код прикрепляю

Файлы:
testDB_NW.mq5  8 kb
 
 Ну почему нельзя input-парамерты перебрать в цикле? За что вы нас так наказываете???
 
x572intraday #:
 Ну почему нельзя input-парамерты перебрать в цикле? За что вы нас так наказываете???

А зачем это надо? Поделитесь секретом…

 
Как устанавливать советники из маркета? У меня несколько терминалов. 
В маркете нажимаю скачать, по умолчанию открывается не тот терминал. Удалил его. Теперь ничего не происходит после нажатия кнопки "скачать"
 
Vladimir Makhnin #:
Как устанавливать советники из маркета? У меня несколько терминалов. 
В маркете нажимаю скачать, по умолчанию открывается не тот терминал. Удалил его. Теперь ничего не происходит после нажатия кнопки "скачать"

каким браузером вы скачиваете?

 
Alexey Viktorov #:

А зачем это надо? Поделитесь секретом…

 Да вот в соседней ветке было, далеко ходить не надо:

enum LIST
  {
   L01=111,   // ITEM 1
   L02=222,   // ITEM 2
   L03=333,   // ITEM 3
   L04=444,   // ITEM 4
   L05=555,   // ITEM 5
   L06=666,   // ITEM 6
   L07=777,   // ITEM 7
   L08=888,   // ITEM 8
  };

input LIST LISTING_01=L01;
input LIST LISTING_02=L02;
input LIST LISTING_03=L03;
input LIST LISTING_04=L04;
input LIST LISTING_05=L05;
input LIST LISTING_06=L06;
input LIST LISTING_07=L07;
input LIST LISTING_08=L08;

LArray[0]=LISTING_01;
LArray[1]=LISTING_02;
LArray[2]=LISTING_03;
LArray[3]=LISTING_04;
LArray[4]=LISTING_05;
LArray[5]=LISTING_06;
LArray[6]=LISTING_07;
LArray[7]=LISTING_08;

 Собачья радость — заталкивать в массив LArray всё руками вместо цикла. И это только пример. В действительности перечислений может быть уйма.

 Про отсутствие возможности перебора enum и ENUM_TIMEFRAMES я вообще молчу. Утомило.
 
x572intraday #:
 Про отсутствие возможности перебора enum и ENUM_TIMEFRAMES я вообще молчу.

Когда-то давно пробовал делать подобный перебор ради интереса:

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Общайтесь с разработчиками через Сервисдеск!

Mihail Matkovskij, 2019.10.05 22:07

Будет очень к стати, если нужно сделать смещение или перебор вправо/влево на любое количество констант. Вот что у меня получилось:

#property script_show_inputs
//--- input parameters
input uint     shift = 1;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool incE_TF(ENUM_TIMEFRAMES &__tf, int _n = 1) {
  int i = __tf, n = _n;
  if(_n > 0) {
    while(i < PERIOD_W1) {
      i++;
      if(StringFind(EnumToString((ENUM_TIMEFRAMES)i), "PERIOD_", 0) == 0){
        n--;
        if(n == 0) {
          __tf = (ENUM_TIMEFRAMES)i;
          return true;
        }
      }
    }
  }
  else if(_n < 0) {
    while(i > PERIOD_CURRENT) {
      i--;
      if(StringFind(EnumToString((ENUM_TIMEFRAMES)i), "PERIOD_", 0) == 0){
        n++;
        if(n == 0) {
          __tf = (ENUM_TIMEFRAMES)i;
          return true;
        }
      }
    }
  }
  return false;
}

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart() {
  ENUM_TIMEFRAMES i;
  i = PERIOD_CURRENT;
  Print("Go");
  Print(EnumToString(i), " = ", i);
  while(i < PERIOD_W1) {
    if(!incE_TF(i, shift))
      break;
    Print(EnumToString(i), " = ", i);
  }
  i = PERIOD_W1;
  Print("Back");
  Print(EnumToString(i), " = ", i);
  while(i > PERIOD_CURRENT) {
    if(!incE_TF(i, -shift))
      break;
    Print(EnumToString(i), " = ", i);
  } 
}

Смещение на 1:

2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     Go
2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     PERIOD_CURRENT = 0
2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M1 = 1
2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M2 = 2
2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M3 = 3
2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M4 = 4
2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M5 = 5
2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M6 = 6
2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M10 = 10
2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M12 = 12
2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M15 = 15
2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M20 = 20
2019.10.05 23:04:12.198 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M30 = 30
2019.10.05 23:04:12.204 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H1 = 16385
2019.10.05 23:04:12.204 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H2 = 16386
2019.10.05 23:04:12.204 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H3 = 16387
2019.10.05 23:04:12.204 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H4 = 16388
2019.10.05 23:04:12.204 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H6 = 16390
2019.10.05 23:04:12.204 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H8 = 16392
2019.10.05 23:04:12.204 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H12 = 16396
2019.10.05 23:04:12.204 EnumTimeframeIteration (EURUSD,M12)     PERIOD_D1 = 16408
2019.10.05 23:04:12.210 EnumTimeframeIteration (EURUSD,M12)     PERIOD_W1 = 32769
2019.10.05 23:04:12.210 EnumTimeframeIteration (EURUSD,M12)     Back
2019.10.05 23:04:12.210 EnumTimeframeIteration (EURUSD,M12)     PERIOD_W1 = 32769
2019.10.05 23:04:12.217 EnumTimeframeIteration (EURUSD,M12)     PERIOD_D1 = 16408
2019.10.05 23:04:12.217 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H12 = 16396
2019.10.05 23:04:12.217 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H8 = 16392
2019.10.05 23:04:12.217 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H6 = 16390
2019.10.05 23:04:12.217 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H4 = 16388
2019.10.05 23:04:12.217 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H3 = 16387
2019.10.05 23:04:12.217 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H2 = 16386
2019.10.05 23:04:12.217 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H1 = 16385
2019.10.05 23:04:12.223 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M30 = 30
2019.10.05 23:04:12.223 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M20 = 20
2019.10.05 23:04:12.223 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M15 = 15
2019.10.05 23:04:12.223 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M12 = 12
2019.10.05 23:04:12.223 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M10 = 10
2019.10.05 23:04:12.223 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M6 = 6
2019.10.05 23:04:12.223 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M5 = 5
2019.10.05 23:04:12.223 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M4 = 4
2019.10.05 23:04:12.223 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M3 = 3
2019.10.05 23:04:12.223 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M2 = 2
2019.10.05 23:04:12.223 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M1 = 1
2019.10.05 23:04:12.223 EnumTimeframeIteration (EURUSD,M12)     PERIOD_CURRENT = 0

Смещение на 2:

2019.10.05 23:06:11.462 EnumTimeframeIteration (EURUSD,M12)     Go
2019.10.05 23:06:11.462 EnumTimeframeIteration (EURUSD,M12)     PERIOD_CURRENT = 0
2019.10.05 23:06:11.462 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M2 = 2
2019.10.05 23:06:11.462 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M4 = 4
2019.10.05 23:06:11.462 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M6 = 6
2019.10.05 23:06:11.463 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M12 = 12
2019.10.05 23:06:11.463 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M20 = 20
2019.10.05 23:06:11.469 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H1 = 16385
2019.10.05 23:06:11.469 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H3 = 16387
2019.10.05 23:06:11.469 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H6 = 16390
2019.10.05 23:06:11.469 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H12 = 16396
2019.10.05 23:06:11.475 EnumTimeframeIteration (EURUSD,M12)     PERIOD_W1 = 32769
2019.10.05 23:06:11.475 EnumTimeframeIteration (EURUSD,M12)     Back
2019.10.05 23:06:11.475 EnumTimeframeIteration (EURUSD,M12)     PERIOD_W1 = 32769
2019.10.05 23:06:11.482 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H12 = 16396
2019.10.05 23:06:11.482 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H6 = 16390
2019.10.05 23:06:11.482 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H3 = 16387
2019.10.05 23:06:11.482 EnumTimeframeIteration (EURUSD,M12)     PERIOD_H1 = 16385
2019.10.05 23:06:11.488 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M20 = 20
2019.10.05 23:06:11.488 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M12 = 12
2019.10.05 23:06:11.488 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M6 = 6
2019.10.05 23:06:11.488 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M4 = 4
2019.10.05 23:06:11.488 EnumTimeframeIteration (EURUSD,M12)     PERIOD_M2 = 2
2019.10.05 23:06:11.488 EnumTimeframeIteration (EURUSD,M12)     PERIOD_CURRENT = 0

Правда данный способ всё же проигрывает в скорости способу со switch.

Так что всё возможно если захотеть!
 
x572intraday #:
 Ну почему нельзя input-парамерты перебрать в цикле? За что вы нас так наказываете???

Присоединяюсь к вопросу.

Да и по enum тоже: Если есть функция EnumToString, то почему нет StringToEnum - там какая-то невероятно сложная задача?

Сохранять значения перечислений в БД в виде чисел не вариант же, так как если потом добавил в enum посредине какое-то новое значения - все, данные в БД превратились в тыкву, да и нечитаемые они в виде чисел, глазами не просмотреть.

 

Есть ли возможность явно передать в параметр запроса БД значение NULL?

Вот такая конструкция вызывает ошибку компиляции:

res = DatabaseBind(request, column, NULL);
 
Maksim Emeliashin #:

Есть ли возможность явно передать в параметр запроса БД значение NULL?

Вот такая конструкция вызывает ошибку компиляции:

DatabaseBind(request, column, "");
Причина обращения: