Проверка существования таблицы в базе данных

Встроенная функция DatabaseTableExists позволяет проверить наличие таблицы по её имени.

bool DatabaseTableExists(int database, const string table)

Дескриптор базы и имя таблицы задаются в параметрах.

Результат вызова функции равен true, если таблица существует.

Дополним класс DBSQLite соответствующим методом hasTable.

class DBSQLite
{
   ...
   bool hasTable(const string tableconst
   {
      return DatabaseTableExists(handletable);
   }

В скрипте DBcreateTable.mq5 убедимся в появлении таблицы.

void OnStart()
{
   DBSQLite db(Database);
   if(db.isOpen())
   {
      PRTF(db.execute(StringFormat("CREATE TABLE %s (msg text)"Table)));
      PRTF(db.hasTable(Table));
   }
}

Опять же, не смущаемся потенциальной возможности получить ошибку при попытке повторного создания. Это никак не влияет на наличие таблицы.

database error, table table1 already exists
db.execute(StringFormat(CREATE TABLE %s (msg text),Table))=false / DATABASE_ERROR(5601)
db.hasTable(Table)=true / ok

Поскольку мы пишем универсальный вспомогательный класс DBSQLite, предусмотрим в нем механизм удаления таблиц. Напомним, что в SQL для этой цели есть команда DROP.

class DBSQLite
{
   ...
   bool deleteTable(const string nameconst
   {
      const static string query = "DROP TABLE '%s';";
      if(!DatabaseTableExists(handlename)) return true;
      if(!DatabaseExecute(handleStringFormat(queryname))) return false;
      return !DatabaseTableExists(handlename)
         && ResetLastErrorOnCondition(_LastError == DATABASE_NO_MORE_DATA);
   }
   
   static bool ResetLastErrorOnCondition(const bool cond)
   {
      if(cond)
      {
         ResetLastError();
         return true;
      }
      return false;
   }

Перед выполнением запроса мы проверяем наличие таблицы и сразу выходим, если её нет.

После выполнения запроса мы дополнительно проверяем, удалилась ли таблица, повторным вызовом DatabaseTableExists. Поскольку отсутствие таблицы будет помечено кодом ошибки DATABASE_NO_MORE_DATA, а для данного метода это ожидаемый результат, мы очищаем код ошибки с помощью ResetLastErrorOnCondition.

В принципе, более эффективно использовать возможности самого SQL для исключения попытки удаления несуществующей таблицы: достаточно добавить в запрос фразу "IF EXISTS". Поэтому окончательный вариант метода deleteTable упрощается:

   bool deleteTable(const string nameconst
   {
      const static string query = "DROP TABLE IF EXISTS '%s';";
      return DatabaseExecute(handleStringFormat(queryname));
   }

Вы можете попробовать написать проверочный скрипт для удаления таблицы самостоятельно, но будьте осторожны, чтобы в зависимости от входных переменных по ошибке не удалить какую-нибудь рабочую таблицу. Таблицы удаляются сразу со всеми данными, без запросов подтверждения и без возможности восстановления. Для важных проектов сохраняйте бэкапы баз.