MySQL Connector / NET的MySqlCommand不使用参数

时间:2014-05-16 02:41:38

标签: c# mysql sql datetime parameterization

所以我在使用MySQL连接器时遇到了一些问题(特别是针对.NET)。通常情况下,我不会使用参数化 - 虽然我知道这样做会使我的程序容易受到SQL注入。

然而,不幸的是,我不能这样做;我需要存储一个字节数组(从该程序的客户端读取图像文件派生的字节数)到MySQL数据库。显然,将字节数组放入查询字符串是不行的;那就是" System.Byte[]"进入阵列。

我之前使用过参数化查询 - 但仅限于。以下是我的代码,其中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 Connector / 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类型{ {1}})或者那种程度的东西。

这显然意味着参数不会被其值替换。 DateTime不是?dateTime字段的有效值,因为它必须采用DateTime格式,因此连接器会抛出异常。但是我做错了什么?

提前感谢您提供任何帮助 - 我曾经习惯于在Java中执行与数据库相关的事情(以及套接字逻辑等),但这是一个学校项目,需要在C#中完成。

1 个答案:

答案 0 :(得分:3)

那些看起来不像有效的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