MySql.Data ExecuteNonQuery抛NullReferenceException且生成空行问题
问题:使用MySql.Data创建表时抛出NullReferenceException且出现空记录
场景与代码
项目已安装MySql.Data NuGet包,尝试通过ExecuteNonQuery执行DDL创建表,代码如下:
using (MySqlConnection con = new MySqlConnection(connectionString)) { con.Open(); MySqlCommand sqlCommand = new MySqlCommand(); sqlCommand.Connection = con; string cmd = @"CREATE TABLE [TABLENAME] ( TIMESTAMP VARCHAR(30) NOT NULL, TAGNAME NVARCHAR(250) NOT NULL, MESSAGE NVARCHAR(1000) NOT NULL, LIMITTYPE NVARCHAR(100) NOT NULL, CLASSNAME NVARCHAR(100) NOT NULL, STATE NVARCHAR(20) NOT NULL, PRIMARY KEY (TIMESTAMP, TAGNAME), KEY IDX_[TABLENAME] (TIMESTAMP, TAGNAME) ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; sqlCommand.CommandText = cmd.Replace("[TABLENAME]", tableName); sqlCommand.ExecuteNonQuery(); }
异常现象
- 执行
sqlCommand.ExecuteNonQuery();时抛出NullReferenceException,堆栈跟踪如下:
at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId) at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId) at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force) at MySql.Data.MySqlClient.MySqlDataReader.NextResult() at MySql.Data.MySqlClient.MySqlDataReader.Close() at MySql.Data.MySqlClient.MySqlDataReader.Dispose(Boolean disposing) at MySql.Data.MySqlClient.MySqlDataReader.Dispose() at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
- MySQL Workbench中可见表已成功创建,但出现一条全字段为NULL的非法记录(所有字段均设置
NOT NULL约束);直接在Workbench中执行相同SQL语句则无此问题,需求仅为创建表,无需插入数据。
原因分析
- MySql.Data驱动版本缺陷:旧版本的MySql.Data(尤其是8.0之前的版本)在处理
CREATE TABLE这类DDL语句时,内部逻辑错误地尝试读取结果集,当无结果返回时触发NullReferenceException,同时错误生成空记录。 - SQL语法不符合MySQL规范:MySQL使用反引号
`作为标识符包裹符,而非SQL Server风格的[],虽然部分场景下[]能被兼容解析,但可能导致驱动的SQL解析逻辑异常,进而触发错误行为。
解决方法
- 升级MySql.Data版本:将NuGet包升级至最新稳定版(推荐8.0及以上),新版本已修复DDL语句的处理逻辑bug。
- 修正SQL标识符语法:将SQL中的
[TABLENAME]替换为MySQL标准的`[TABLENAME]`,避免解析异常:string cmd = @"CREATE TABLE `[TABLENAME]` ( TIMESTAMP VARCHAR(30) NOT NULL, TAGNAME NVARCHAR(250) NOT NULL, MESSAGE NVARCHAR(1000) NOT NULL, LIMITTYPE NVARCHAR(100) NOT NULL, CLASSNAME NVARCHAR(100) NOT NULL, STATE NVARCHAR(20) NOT NULL, PRIMARY KEY (TIMESTAMP, TAGNAME), KEY `IDX_[TABLENAME]` (TIMESTAMP, TAGNAME) ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; sqlCommand.CommandText = cmd.Replace("[TABLENAME]", tableName); - 替换为MySqlConnector驱动:Oracle维护的MySql.Data存在较多遗留问题,MySqlConnector是社区维护的替代方案,兼容性更强、bug修复更及时,可彻底避免此类问题。
内容的提问来源于stack exchange,提问作者jinsik556
相关产品推荐
相关产品推荐

