Comprobar si una tabla existe en la base de datos

La función integrada DatabaseTableExists permite comprobar la existencia de una tabla por su nombre.

bool DatabaseTableExists(int database, const string table)

El descriptor de la base de datos y el nombre de la tabla se especifican en los parámetros. El resultado de la llamada a la función es true si la tabla existe.

Vamos a ampliar la clase DBSQLite añadiendo el método hasTable.

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

El script DBcreateTable.mq5 comprobará si la tabla ha aparecido.

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

Una vez más, no se preocupe por la posibilidad de obtener un error al intentar volver a crear. Esto no afecta en modo alguno a la existencia de la tabla.

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

Dado que estamos escribiendo una clase de ayuda genérica DBSQLite, proporcionaremos un mecanismo para eliminar tablas en ella. SQL tiene el comando DROP para este propósito.

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;
   }

Antes de ejecutar la consulta, comprobamos la existencia de la tabla y salimos inmediatamente si no existe.

Después de ejecutar la consulta, comprobamos además si la tabla se ha borrado volviendo a llamar a DatabaseTableExists. Dado que la ausencia de una tabla se marcará con el código de error DATABASE_NO_MORE_DATA, que es el resultado esperado para este método, borramos el código de error con ResetLastErrorOnCondition.

Puede ser más eficaz utilizar las capacidades de SQL para excluir un intento de eliminar una tabla inexistente: basta con añadir la frase «IF EXISTS» a la consulta. Por lo tanto, la versión final del método deleteTable está simplificada:

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

Puede intentar escribir un script de prueba para borrar la tabla, pero tenga cuidado de no borrar una tabla de trabajo por error. Las tablas se borran inmediatamente con todos los datos, sin confirmación y sin posibilidad de recuperación. Para proyectos importantes, guarde copias de seguridad de la base de datos.