我想通过我的c#应用程序(使用Connector / Net 8.0.11)将行插入MySql数据库。我正在使用命令参数来传递值,因为 - 在我的理解中 - 我不必关心任何类型的特殊字符。请在下面找到简化的代码示例。
MySqlCommand Cmd = new MySqlCommand("INSERT INTO testtab(TestCol1,TestCol2) VALUES(@test1,@test2)", Con);
Cmd.Parameters.AddWithValue("@test1", "12'34");
Cmd.Parameters.AddWithValue("@test2", "56");
Cmd.ExecuteNonQuery();
但“12'34”中的单引号会导致异常:
“您的SQL语法有错误;请查看手册 对应于您的MySQL服务器版本,以便使用正确的语法 靠近'34','56')'在第1行“
我知道我根本就不能使用参数,只是将我的值字符串中的引号加倍...但我使用Connector / ODBC构建了类似的应用程序,它们工作正常。你能帮我找一下Connector / Net的技巧吗?
答案 0 :(得分:0)
我非常感谢女士们和先生们的帮助 - 特别感谢Progman,您的评论解决了我的问题。
我现在回答我自己的问题来总结一下。有三种可能的解决方案:
整个问题与SQL模式NO_BACKSLASH_ESCAPES有关。一种解决方案可能是关闭特定的SQL模式。
fubo在评论中提到:
MySql.Data.MySqlClient.MySqlHelper.EscapeString("12'34")
的转义结果为12\'34
这很奇怪,但SQL模式NO_BACKSLASH_ESCAPES与参数值的转义字符串挣扎(imo这是Connector / Net中的一个错误,因为Connector / ODBC工作正常)。另一种解决方案可能是使用Connector / ODBC。
对我来说最后的伎俩是Progmans评论:
根据dev.mysql.com/doc/connector-net/en/…,您必须在添加值之前调用Prepare()。
这更像是一种解决方法,但如果您同时使用SQL模式NO_BACKSLASH_ESCAPES和命令参数,则必须在调用Prepare()
之前调用ExecuteNonQuery()
。请注意 - 与开发人员指南中的示例不同 - 我在添加参数之前无法调用它(您将获得异常),并且我将IgnorePrepare=false
添加到连接字符串。我假设其工作原因是因为它改变了客户端和服务器之间的数据传输:
预准备语句的另一个优点是,在启用服务器端预处理语句的情况下,它使用二进制协议,使客户端和服务器之间的数据传输更加高效。
以下是适用于我的代码段:
//add IgnorePrepare=false to the connection string
MySqlConnection Con = new MySqlConnection("Server = localhost; Port = 3306; Database = param_test; Uid = ***; Pwd = ***; SslMode=none; IgnorePrepare=false");
Con.Open();
MySqlCommand Cmd = new MySqlCommand("INSERT INTO testtab(TestCol1,TestCol2) VALUES(@test1,@test2)", Con);
Cmd.Parameters.AddWithValue("@test1", "12'34");
Cmd.Parameters.AddWithValue("@test2", "56");
Cmd.Prepare(); //calling it after Adding the parameters works fine
Cmd.ExecuteNonQuery();