我有一个应用程序,它使用一个类来创建一个完整的MySQL数据库供应用程序使用。该类使用单独的方法来创建每个表。
对话框用于允许创建表,因为存在用于在组中创建的不同用途的表。每个组创建按钮的基础代码连续执行上述类中的表创建方法。
每个表创建方法使用两个查询。第一个是
DROP TABLE IF EXISTS tablename
第二个查询是表定义CREATE TABLE ...
如果数据库为空,则表都已成功创建。
如果表存在并且我从头开始重新创建表,则在尝试重新创建表时会收到错误(错误121)。这很奇怪,因为重新创建的表没有PRIMARY KEY而NONE有外键!我假设errno 121即将上映,因为即使桌子已被丢弃,桌子仍然会出现在那里。
如果我使用MySQL Workbench手动删除表并再次运行表创建,一切都很顺利,所有表都会再次成功创建。
在运行CREATE TABLE查询之前,似乎DROP TABLE查询未完成或对程序可见。 DROP TABLE最终成功,因为当我签入MySQL Workbench时,该表不再出现在数据库中。
我使用相同的MySQL命令对象来运行两个查询。执行DROP TABLE查询后,我更改了CREATE TABLE查询的CommandText属性。我也尝试使用不同的MySQL命令对象,使用不同的MySQL连接对象,结果相同。
知道为什么在CREATE TABLE查询之前没有完成或识别DROP TABLE查询?
我在Windows 8上运行MySQL 5.1.39(在Windows 7上的结果相同),在Visual Studio 2008中用C#中的MySQL Connector / NET 6.5.4运行。
根据下面的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
(错误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,但没有做任何事情。
希望这有帮助!
答案 0 :(得分:0)
好的,这个属于Twilight Zone!
SH建议我尝试使用干净的新数据库。因此,我创建了一个新模式,并创建了数据库中存在问题的所有表,视图,触发器和例程。然后,我使用旧数据库中完全相同的数据填充新数据库中的所有表。这完全取决于我的应用程序的功能。
我运行了导致新数据库出现一致问题的代码,一切正常。我可以运行代码重建表格和恶心,从未收到错误。我还能够运行更新对话框,该对话框改变所选表格以添加新列而不会出现问题。
为了完整起见,我删除了原始模式,并以与新测试模式相同的方式从头开始重新创建它以及所有表,视图,触发器和例程,并将数据从测试表中复制回来。一切都运行得很好,我不能再产生任何错误。
很明显,由于许多表出现问题,原始数据库的模式定义存在一些问题。当我构建Windows 8系统时,我使用PhpMyAdmin Export从旧的Windows 7环境迁移模式,并使用MySQL Workbench将它们加载到Windows 8中。 MysQL服务器版本在Windows 8和Windows 7上是相同的。也许在导出和导入之间存在遗漏或某种故障。我永远不会知道。
这一切现在都在运作,我很欣赏SH的意见和建议。
我会将这一个与Word文档放在同一堆中,这个文档总是会导致BSOD - 即使对于Microsoft也是如此!以及在测试期间导致BSOD的Oracle数据库,直到我们删除用户ID 666!以及一直返回错误结果的类,直到我将其完全复制到新类,并返回正确的结果!
答案 1 :(得分:0)
整理信息来自评论
问题:表未正确删除。由于某些未知原因,删除似乎已被推迟。
Troubleshooting Methods used:
Use new MySQL Command in code -> No Change.
Break After First Drop command -> No Change
Check Mysql Logs after first Command -> Locate Error and code.
Verfiy there is no async commands lingering in code -> No Change.
Recreate Error on clean Mysql Db. -> Unrepeatable
解决方案:重新创建完整架构。可能由某种MySql Migration引起的错误。
OP:信息
显然,架构定义存在一些问题 自许多表出现问题以来的原始数据库。当我 构建了我的Windows 8系统,我从旧的Windows迁移了模式 7环境使用PhpMyAdmin导出并加载到Windows 8中 使用MySQL Workbench。 MysQL服务器版本在Windows 8上是相同的 和Windows 7.也许有一些错过或一些故障 在导出和导入之间排序。我永远不会知道。
答案 2 :(得分:0)
如果您的MySQL服务器作为Windows服务运行,则禁用它并从控制台运行MySQL服务器守护程序可能会有所帮助。
我看到的时候有一个案例:
“MySQL试图删除表
Table
... InnoDB:虽然有 仍然打开手柄。“
MySQL错误日志文件中的错误。我意识到MySQL是作为Windows服务安装的,并且它处于“停止”状态。我的解决方案是重新启动PC,这样我就可以完全禁用Windows服务并从控制台运行MySQL守护进程。