mql5中的OOP、模板和宏,细微之处和用途 - 页 28

 
Maxim Kuznetsov:

我记得在SQLite中,字段类型是可选的,你不需要担心指定和铸造类型的问题。它被称为 "Lite "是有原因的。

你可以把一个长的查询分成3-4-5个:-)

BEGIN TRANSACTION

INSERT INTO myTable VALUES (...); --- тут можно получить PrimaryKey

UPDATE myTable .... ; --- обновить по Primary

UPDATE myTable ...  ; --- ещё...

COMMIT ; --- это если все запросы удачны.. иначе ROLLBACK

这是从旧的记忆中来的,所以你应该在帮助中检查。

我希望有一个可复制的查询代码,这将需要很长的时间去谷歌,我偶尔与数据库合作 - 我有一个问题,我去谷歌,我解决了它 - 但我希望看到一个失败的数据库查询

 
Vladimir Simakov:

你的特殊问题应该这样解决。

string MakeRequest(string md5txt){
   static ENUM_STATISTICS intIndex[]={STAT_CONPROFITMAX_TRADES,
                                      STAT_MAX_CONPROFIT_TRADES,
                                      STAT_CONLOSSMAX_TRADES,
                                      STAT_MAX_CONLOSS_TRADES,
                                      STAT_DEALS,
                                      STAT_TRADES,
                                      STAT_PROFIT_TRADES,
                                      STAT_LOSS_TRADES,
                                      STAT_SHORT_TRADES,
                                      STAT_LONG_TRADES,
                                      STAT_PROFIT_SHORTTRADES,
                                      STAT_PROFIT_LONGTRADES,
                                      STAT_PROFITTRADES_AVGCON,
                                      STAT_LOSSTRADES_AVGCON};
   string ret="INSERT INTO \"TesterStatistics\" + StringFormat(" set md5= %d ,md5txt),
   for (int i=0,ii=0;i<=STAT_LOSSTRADES_AVGCON;++i){
      ret+=",";
      if (i==intIndex[ii]){
         ret+=StringFormat("%s = %d,",EnumToString((ENUM_STATISTICS)i),(int)TesterStatistics((ENUM_STATISTICS)i) ));
         ++ii;}
      else ret+=StringFormat("%s =%G",EnumToString((ENUM_STATISTICS),i),TesterStatistics((ENUM_STATISTICS)i));}
   return ret;}
   
DatabaseExecute(handleDB, MakeRequest("md5txt"));

一个小的修正,有更多的括号要修正:-)
主要的想法不是使用UPDATE x VALUES(),而是UPDATE x SET name1=value1,name2=value2。为了使查询在数据库结构改变的情况下正确工作,而不依赖于字段的顺序

 

大约有以下代码(我从数据库中读取文本字段,并希望转换为枚举。)

class MyClass
{
public:
   enum A            {Aq, Aw, Ae, Ar, At, Ay};
   enum B            {Bq, Bw, Be};
   enum C            {Cq, Cw, Ce, Cr};

   static bool       txtToEnumA(const string txt, A &result);
   static bool       txtToEnumB(const string txt, B &result);
   static bool       txtToEnumC(const string txt, C &result);
};
//+------------------------------------------------------------------+
static bool MyClass::txtToEnumA(const string txt, A &result)
{
   for(int i = 0; i <= (int)A::Ay; i++)
   {
      if(StringCompare(EnumToString((A)i), txt) == 0)
      {
         result = (MyClass::A)i;
         return(true);
      }
   }
   return(false);
}
//+------------------------------------------------------------------+
static bool MyClass::txtToEnumB(const string txt, B &result)
{
   for(int i = 0; i <= (int)B::Be; i++)
   {
      if(StringCompare(EnumToString((B)i), txt) == 0)
      {
         result = (MyClass::B)i;
         return(true);
      }
   }
   return(false);
}
//+------------------------------------------------------------------+
static bool MyClass::txtToEnumC(const string txt, C &result)
{
   for(int i = 0; i <= (int)C::Cr; i++)
   {
      if(StringCompare(EnumToString((A)i), txt) == 0)
      {
         result = (MyClass::C)i;
         return(true);
      }
   }
   return(false);
}
//+------------------------------------------------------------------+
void OnStart()
{
   MyClass::A a;
   MyClass::B b;
   MyClass::C c;
   string txt[] = {"Aq", "Bw", "No"};

   if(MyClass::txtToEnumA(txt[0], a)) Print(txt[0], " in A = ", EnumToString(a));
   else Print("Error, ", txt[0], " not in A");

   if(MyClass::txtToEnumB(txt[1], b)) Print(txt[1], " in B = ", EnumToString(b));
   else Print("Error, ", txt[1], " not in B");

   if(MyClass::txtToEnumC(txt[2], c)) Print(txt[2], " in C = ", EnumToString(c));
   else Print("Error, ", txt[2], " not in C");
}
//+------------------------------------------------------------------+

2020.09.01 18:59:02.593 tst (EURUSD,M5) Aq in A = Aq

2020.09.01 18:59:02.593 tst (EURUSD,M5) Bw in B = Bw

2020.09.01 18:59:02.593 tst (EURUSD,M5) Error, No not in C

一切正常,但问题又是关于最佳代码的。

如果有什么方法可以代替txtToEnumA(), txtToEnumB(), txtToEnumC()来写的话

一个模板方法(模板)。

问题是枚举中的元素数量不同。

 

如果有一个枚举,怎么办?

enum A            {Aq=10, Aw=9, Ae=8, Ar=7, At=6, Ay=5};

?

 
Dmitry Fedoseev:

如果有一个枚举,怎么办?

?

对枚举元素进行编号不是问题,不清楚这样做有什么好处

我只有4个枚举,没有编号

问题是,我可能想在枚举中添加新的元素--在我的代码中,我将添加新的元素,而不是最外层的元素--代码可以工作--我不喜欢这个代码的繁琐性。


但我们不是在谈论一些适用于所有场合的通用代码,我们需要在一个模板中的当前任务


SZY: 我不能没有枚举--它很方便,我可以平等地读取源码和数据库中的数据,在数据库中,也许我想手动纠正一些字段....。总的来说,一切都很适合我

 
Igor Makanu:

对枚举的元素进行编号不是问题,但不清楚这样做会有什么后果

我只有4个枚举,没有编号

问题是,我可能想在列表中添加新的项目--在我的代码中,我将添加新的项目,而不是最外层的项目--代码可以工作--我不喜欢代码的不流畅性。


但我们不是在谈论一些适用于所有场合的通用代码,我们需要在一个模板中的当前任务


SZY: 我不能没有枚举--它很方便,我可以平等地读取源码和数据库中的数据,在数据库中,也许我想手动纠正一些字段....。一切都很好,适合我

建立一个全局数组,用{ EnumToString(x), x }对其进行填充。

struct StringID {

   string str;

   int id;

};

StringID IDS[];

和模板将是不必要的。
 
Maxim Kuznetsov:

建立一个全局数组,用{ EnumToString(x), x }对其进行填充。

struct StringID {

   string str;

   int id;

};

StringID IDS[];

而你将不需要模板。

你的方法和我的没有什么不同--也很麻烦,如果代码中会有任何变化,你也必须编辑数组。

 

这样解决了我的愿望。

class MyClass
{
public:
   enum A            {Aq, Aw, Ae, Ar, At, Ay};
   enum B            {Bq, Bw, Be};
   enum C            {Cq, Cw, Ce, Cr};
   template<typename T>
   static bool       txtToEnum(const T LastElement, const string txt, T &result);
};
//+------------------------------------------------------------------+
template<typename T>
static bool MyClass::txtToEnum(const T LastElement, const string txt, T &result)
{
   for(int i = 0; i <= (int)LastElement; i++)
   {
      if(StringCompare(EnumToString((T)i), txt) == 0)
      {
         result = (T)i;
         return(true);
      }
   }
   return(false);
}
//+------------------------------------------------------------------+
void OnStart()
{
   MyClass::A a;
   MyClass::B b;
   MyClass::C c;
   string txt[] = {"Aq", "Bw", "No"};

   if(MyClass::txtToEnum(MyClass::Ay, txt[0], a)) Print(txt[0], " in A = ", EnumToString(a));
   else Print("Error, ", txt[0], " not in A");

   if(MyClass::txtToEnum(MyClass::Be, txt[1], b)) Print(txt[1], " in B = ", EnumToString(b));
   else Print("Error, ", txt[1], " not in B");

   if(MyClass::txtToEnum(MyClass::Cr, txt[2], c)) Print(txt[2], " in C = ", EnumToString(c));
   else Print("Error, ", txt[2], " not in C");

}
//+------------------------------------------------------------------+

2020.09.01 22:08:47.417 tst (EURUSD,M5) Aq in A = Aq

2020.09.01 22:08:47.417 tst (EURUSD,M5) Bw in B = Bw

2020.09.01 22:08:47.417 tst (EURUSD,M5) Error, No not in C



我需要更多的定义,不需要输入LastElement,但总的来说,这段代码更紧凑。

 
写各种各样的东西需要多少钱