我有一个应用程序,它使用一个类来创建一个完整的 MySQL 数据库供应用程序使用。该类使用单独的方法来创建每个表。
对话框用于允许创建表格,因为有用于不同用途的表格以组的形式创建。每个组创建按钮的底层代码依次执行上述类中的表创建方法。
每个表创建方法使用两个查询。第一个是
DROP TABLE IF EXISTS 表名
第二个查询是表定义 CREATE TABLE ...
如果数据库为空,则表都创建成功。
如果表存在并且我从头开始重新创建表,则在尝试重新创建表时收到错误 (errno 121)。这很奇怪,因为重新创建的表中没有一个有主键,没有一个有外键!我假设 errno 121 即将出现,因为该表似乎仍然存在,即使它已被删除。
如果我使用 MySQL Workbench 手动删除表并再次运行表创建,一切都很好,并且所有表都再次成功创建。
在运行 CREATE TABLE 查询之前,DROP TABLE 查询似乎没有完成或对程序可见。DROP TABLE 最终成功,因为当我签入 MySQL Workbench 时,该表不再出现在数据库中。
我使用相同的 MySQL 命令对象来运行这两个查询。执行 DROP TABLE 查询后,我更改了 CREATE TABLE 查询的 CommandText 属性。我也尝试过使用不同的 MySQL 命令对象和不同的 MySQL 连接对象,结果相同。
知道为什么在 CREATE TABLE 查询之前没有完成或识别 DROP TABLE 查询吗?
我在 C# 的 Visual Studio 2008 中使用 MySQL Connector/NET 6.5.4 在 Windows 8 上运行 MySQL 5.1.39(在 Windows 7 上结果相同)。
按照下面 SH 的要求,这里是其中一张表(一个小表)的代码。连接字符串包含默认目录,因此我不必在查询中明确包含它。此版本将查询包装在事务中,而原始版本没有 - 相同的结果。我什至把 DoEvents 作为在黑暗中的一个镜头。
public void CreateViewTableCasualtyLookup()
{
// Declare local variables.
string strSQL = string.Empty;
string strMsg = string.Empty;
string strNewDBName = string.Empty;
MySqlConnection cnNewTable = new MySqlConnection();
MySqlCommand cmdNewTable = new MySqlCommand();
MySqlTransaction tranNewTable = null;
StringBuilder sbSQL = new StringBuilder();
try
{
// Create a connection.
cnNewTable.ConnectionString = m_strServerConnect;
cnNewTable.Open();
cmdNewTable.Connection = cnNewTable;
tranNewTable = cnNewTable.BeginTransaction();
// First we need to drop the exising table.
strSQL = "DROP TABLE IF EXISTS vCasualtyLookup";
cmdNewTable.CommandText = strSQL;
cmdNewTable.ExecuteNonQuery();
tranNewTable.Commit();
Application.DoEvents();
// Create the new table.
tranNewTable = cnNewTable.BeginTransaction();
sbSQL.AppendLine("CREATE TABLE vCasualtyLookup (");
sbSQL.AppendLine("CasualtyID char(10), ");
sbSQL.AppendLine("LookupName varchar(100)) ");
// sbSQL.AppendLine("PRIMARY KEY (LookupName))");
sbSQL.AppendLine(" ENGINE = InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci");
cmdNewTable.CommandText = sbSQL.ToString();
cmdNewTable.ExecuteNonQuery();
tranNewTable.Commit();
Application.DoEvents();
}
catch (Exception ex)
{
tranNewTable.Rollback();
strMsg = "Application Error:\r\n";
strMsg += "An error occurred while trying to create the view table vCasualtyLookup. ";
strMsg += "The full text of the error is shown below:\r\n\r\n";
strMsg += ex.Message;
throw new ApplicationException(strMsg);
}
finally
{
// Clear objects from memory.
if (tranNewTable != null)
{
tranNewTable.Dispose();
}
if (cmdNewTable != null)
{
cmdNewTable.Dispose();
}
if (cnNewTable != null)
{
if (cnNewTable.State == System.Data.ConnectionState.Open)
{
cnNewTable.Close();
}
cnNewTable.Dispose();
}
if (sbSQL != null)
{
sbSQL = null;
}
}
} // end CreateViewTableCasualtyLookup
当执行此表和其他表的方法时,MySQL Workbench 报告 DROP TABLE 必须已完成,因为该表不再存在。当 CREATE TABLE 被执行时,它会产生一个异常:
“无法创建表casualtyutf8.vCasualtyLookup
(errno 121)”
在 Locals 窗口中检查 ex 变量显示“base”错误代码为“-2147467259”,MySQL 异常“Number”为“1005”。
我刚刚检查了 MySQL 错误日志文件,它显示:
InnoDB: Warning: MySQL is trying to drop table `casualtyutf8`.`vcasualtyassignnarratives`
InnoDB: though there are still open handles to it.
InnoDB: Adding the table to the background drop queue.
下一个条目是表已存在的 INNODB 错误。我不知道其他进程可以打开表的句柄,除非它是 Visual Studio 调试器。我关闭了应用程序并关闭了 Visual Studio,但这并没有做任何事情。
希望这可以帮助!