因此,在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();
}
}
为什么会发生这种情况?我该如何解决这个问题?我已经看到很多关于这方面的问题,但不是一个具体的答案。
答案 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);