检查数据库中是否存在表
内置的 DatabaseTableExists 函数允许通过其名称检查表是否存在。
bool DatabaseTableExists(int database, const string table)
数据库描述符和表名在参数中指定。如果表存在,函数调用的结果为 true。
我们通过添加 hasTable 方法来扩展 DBSQLite 类。
class DBSQLite
{
...
bool hasTable(const string table) const
{
return DatabaseTableExists(handle, table);
}
|
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 name) const
{
const static string query = "DROP TABLE '%s';";
if(!DatabaseTableExists(handle, name)) return true;
if(!DatabaseExecute(handle, StringFormat(query, name))) return false;
return !DatabaseTableExists(handle, name)
&& 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 name) const
{
const static string query = "DROP TABLE IF EXISTS '%s';";
return DatabaseExecute(handle, StringFormat(query, name));
}
|
你可以尝试编写一个用于删除表的测试脚本,但小心不要错误地删除了工作表。表会连同所有数据立即删除,不会提示确认,也无法恢复。对于重要项目,请保留数据库备份。