【问题标题】:MySql command parameters with quotes带引号的 MySql 命令参数
【发布时间】:2018-05-17 14:18:41
【问题描述】:

我想通过我的 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 服务器版本,以便使用正确的语法 在第 1 行的 '34','56')' 附近"

我知道我根本不能使用参数,而只是将值字符串中的引号加倍......但我已经使用连接器/ODBC 构建了类似的应用程序,它们工作正常。你能帮我找出连接器/网络的诀窍吗?

【问题讨论】:

  • 我更关心near '34','56' 部分。看起来 MySQL 连接器在没有正确转义的情况下是如何内联查询的。您可以尝试在其中放置一个 sql 注入查询,看看它是否有效?喜欢("@test2", "1'; DELETE FROM testtab WHERE ('1' = '1");
  • @PaulF 我的错误
  • MySql.Data.MySqlClient.MySqlHelper.EscapeString("12'34") 的转义结果是12\'34 但不应该是12''34吗?
  • @Steve 仍然遇到像...near '; DELETE FROM testtab WHERE (\'1\' = \'1')' 这样的异常。我认为连接器并不完全内联它。
  • @m.denis 根据dev.mysql.com/doc/connector-net/en/…,您必须在添加值之前调用Prepare()。有帮助吗?

标签: c# mysql


【解决方案1】:

非常感谢您的帮助女士们先生们 - 特别感谢 Progman,您的评论解决了我的问题。

我现在将回答我自己的问题来总结一下。有 3 种可能的解决方案:

整个问题与 SQL 模式 NO_BACKSLASH_ESCAPES 有关。一种解决方案可能是关闭特定的 SQL 模式。

fubo 在他的评论中提到:

MySql.Data.MySqlClient.MySqlHelper.EscapeString("12'34")的转义结果是12\'34

这很奇怪,但是 SQL 模式 NO_BACKSLASH_ESCAPES 难以处理参数值的转义字符串(imo 这是 Connector/Net 中的一个错误,因为 Connector/ODBC 工作正常)。另一种解决方案可能是使用连接器/ODBC。

对我来说最后一招是 Progman 的评论:

根据dev.mysql.com/doc/connector-net/en/…,您必须在添加值之前调用 Prepare()。

这更像是一种变通方法,但是如果您同时使用 SQL 模式 NO_BACKSLASH_ESCAPES 和命令参数,则必须在调用 ExecuteNonQuery() 之前调用 Prepare()。请注意 - 与开发人员指南中的示例不同 - 在添加参数之前我无法调用它(您会遇到异常),并且我将 IgnorePrepare=false 添加到连接字符串中。我认为这样做的原因是因为它改变了客户端和服务器之间的数据传输:

prepared statements 的另一个优点是,启用服务器端prepared statements 后,它使用二进制协议,使客户端和服务器之间的数据传输更加高效。

这是适合我的代码 sn-p:

//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();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多