MySQL 连接器/NET 的 MySqlCommand 不使用参数

Posted

技术标签:

【中文标题】MySQL 连接器/NET 的 MySqlCommand 不使用参数【英文标题】:MySQL Connector/NET's MySqlCommand not using Parameters 【发布时间】:2014-07-04 16:49:53 【问题描述】:

所以我在使用 mysql 连接器时遇到了一些问题(特别是针对 .NET)。通常,我不会使用参数化——尽管我意识到这样做会使我的程序容易受到 SQL 注入的影响。

不幸的是,我不能这样做。我需要将一个字节数组(这些字节来自于在该程序的客户端读取图像文件)存储到 MySQL 数据库中。显然,将字节数组放入查询字符串是行不通的。这只会将“System.Byte[]”放入数组中。

我以前使用过参数化查询——但仅限于java。以下是我的代码,其中packet 是一个我保证在所有情况下都会返回正确数据的对象(出于测试目的,我什至添加了一个包含所有硬编码数据的驱动程序类)和Server保证单例的连接是开放有效的。

MySqlCommand cmd = new MySqlCommand("insert into `screenshots` (`playerId`, `serverId`, `data`, `uploadDate`, `uploadingUserId`) values(?playerId, ?serverId, \"?attachmentData\", \"?dateTime\", ?userId,)", Server.getSingleton().getDbManager().getConnection());
cmd.Parameters.AddWithValue("?playerId", packet.getPlayerId()); //string of an integer
cmd.Parameters.AddWithValue("?serverId", packet.getServerId()); //string of an integer
cmd.Parameters.AddWithValue("?attachmentData", packet.getAttachmentData()); //byte[]
cmd.Parameters.AddWithValue("?dateTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
cmd.Parameters.AddWithValue("?userId", packet.getUserId()); //string of an integer
cmd.executeNonQuery();

我遇到的问题是 MySql 连接器/NET 似乎永远不会用它们的值替换参数。我试过实例化一个new MySqlParameter 对象,设置它的Value,然后调用cmd.Parameters.Add(...),但这会出现同样的问题。

我查看了 MySQL 文档,它说要使用 MySqlCommmand#Parameters.AddWithValue(string, object),并且我没有遗漏其他步骤。

每当我将 Visual Studio 的调试器附加到进程时,可以看到参数已全部添加到 Parameters 列表属性中;但是,当查询执行时,即时调试器会停止执行并突出显示带有cmd.executeNonQuery() 的行,表示'?dateTime' is not a valid value for column 'dateTime'(其中dateTime 列的SQL 类型为DateTime)或其他内容那种程度。

这显然意味着参数没有被它们的值替换。 ?dateTime 不是DateTime 字段的有效值,因为它必须采用yyyy-MM-dd HH:mm:ss 的格式,因此连接器会引发异常。但是我做错了什么?

提前感谢您的帮助——我习惯于用 Java 做与数据库相关的事情(以及套接字逻辑等),但这是一个学校项目,需要用 C# 完成。

【问题讨论】:

【参考方案1】:

那些看起来不像是有效的 MySQL 参数;如果您想要命名参数,请使用@yournamehere,如下所示:

MySqlCommand cmd = new MySqlCommand("insert into `screenshots` (`playerId`, `serverId`, `data`, `uploadDate`, `uploadingUserId`) values(@playerId, @serverId, @attachmentData, @dateTime, @userId)", Server.getSingleton().getDbManager().getConnection());
cmd.Parameters.AddWithValue("@playerId", packet.getPlayerId());

你也不应该引用参数; ADO.NET 将根据目标列的数据类型在必要时执行此操作。

来源:http://dev.mysql.com/doc/connector-net/en/connector-net-tutorials-parameters.html

【讨论】:

根据你对 MySQL 的引用,它似乎已经过时了——我实际上是自己阅读了那个页面;但是,我还遇到了 MySQL Connector/NET 的某个版本的发行说明,它指出 @ 已更改为 ? 以支持用户(例如,user@localhost 将无效,因为它会尝试找到一个参数)。当然,有一种方法可以使用连接字符串选项将参数改回@。但是,我将研究引用参数。 呃,我为不尝试删除引号而感到非常愚蠢——我认为 C# 对我不会那么好。删除它们有效,但参数使用? 转义。谢谢! @DanJesensky 嗯。文档说“此选项在 Connector/Net 5.2.2 中已弃用。现在所有代码都应使用 '@' 符号作为参数标记来编写。” - 您使用的是什么版本的连接器? 我不确定我在哪里读到它了,但我记得在 *** 上看到一堆问题,使用 ? 而不是 @。我将编辑我的代码以改用@。再次感谢。

以上是关于MySQL 连接器/NET 的 MySqlCommand 不使用参数的主要内容,如果未能解决你的问题,请参考以下文章

用于mac的Mysql连接器.net

MySQL 连接器/NET 的 MySqlCommand 不使用参数

MySQL 连接器 6.3.5 与 .NET 3.5

MySql 连接未使用 .net MySql 连接器关闭

.net 中连接mysql

.net写DOS窗口程序,怎么连接mysql??