带引号

时间:2018-05-17 14:18:41

标签: c# mysql

我想通过我的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的技巧吗?

1 个答案:

答案 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();