在SQL命令字符串中出现@whatever会给我一个致命的错误

时间:2012-12-13 13:00:48

标签: c# mysql

因此,在SQL命令字符串中出现@whatever会给我一个致命错误(在命令执行期间遇到致命错误。)但在MySQL查询浏览器中执行相同查询时却没有。

这是一个简单的例子,我在表格中为每个John提供一个行号,并在datagridview中显示它们:

private void button1_Click(object sender, EventArgs e)
{
   _dataTable.Clear();

   try
   {
      _conn = new MySqlConnection(Cs);
      _conn.Open();

      string name = "john";
      //This is the string that gives me an error
      string ConnString = "SELECT name,lastname,(@Row := @Row + 1) AS RowNumber FROM person JOIN (SELECT @Row := 0) r WHERE name = '"+name+"'";

      //This one doesn't gives an error
      //string ConnString = "SELECT name,lastname FROM person WHERE name = '" + name + "'";

      _cmd = new MySqlCommand
      {
         Connection = _conn,
         CommandText = ConnString
      };

      _cmd.ExecuteNonQuery();

      _da = new MySqlDataAdapter(_cmd);
      _da.Fill(_dataTable);

      _cb = new MySqlCommandBuilder(_da);

      dataGridView1.DataSource = _dataTable;
      dataGridView1.DataMember = _dataTable.TableName;
      dataGridView1.AutoResizeColumns();

      _conn.Close();
  }   
  catch (Exception ex)
  {
     MessageBox.Show(ex.Message);
  }
  finally
  {
     if (_conn != null) _conn.Close();
  }
}

为什么会发生这种情况?我该如何解决这个问题?我已经看到很多关于这方面的问题,但不是一个具体的答案。

2 个答案:

答案 0 :(得分:1)

您不应该像这样构建SQL语句。而是使用参数。见SQL Injection。 e.g,

var command = new SqlCommand("SELECT name,lastname,(@Row := @Row + 1) AS" 
                             " RowNumber FROM person JOIN (SELECT @Row := 0)"
                             " r WHERE name = @Name");
SqlParameter param  = new SqlParameter();
param.ParameterName = "@Name";
param.Value         = "John Doe";
command.Parameters.Add(param);

无论如何,这不是连接字符串!

要使用用户定义的参数,您需要设置一个选项。您看到的错误是查询问题,因为C#认为您尝试使用@Row作为参数。见How can I use a MySql User Defined Variable in a .NET MySqlCommand。将其添加到您的连接字符串;Allow User Variables=True。关于此问题还有blog post

此外,您使用的是什么版本的MySQL数据提供程序?您可能需要更新。

我在5.0文档中找到了这个:

“提供程序的早期版本使用'@'符号标记SQL中的参数。这与MySQL用户变量不兼容,因此提供程序现在使用'?'用于在SQL中查找参数的符号。要支持旧代码,可以在连接字符串上设置'old syntax = yes'。如果这样做,请注意如果您未能定义参数,则不会抛出异常打算在你的SQL中使用。“

从此页面:http://dev.mysql.com/doc/refman/5.0/es/connector-net-examples-mysqlcommand.html

因此,使用@参数的@Name符号可能无法在MySQL中使用,您需要使用?Name作为参数,@Row作为用户变量。

e.g,

var command = new SqlCommand("SELECT name,lastname,(@Row := @Row + 1) AS" 
                             " RowNumber FROM person JOIN (SELECT @Row := 0)"
                             " r WHERE name = ?Name");

答案 1 :(得分:-1)

您可能需要在查询中声明@Row。

string command = "DECLARE @Row INT; SELECT name,lastname,(@Row := @Row + 1) AS RowNumber FROM person JOIN (SELECT @Row := 0) r WHERE name = @Name;";

_cmd = new MySqlCommand(_conn);
_cmd.CommandText = command;
_cmd.Parameters.Add("@Name", name);