我正在尝试编写一个小类,它将帮助我使用C#和winforms连接到MySQL服务器。 我编写了可以启动和关闭连接的连接。
我在这里要做的是在这个类中创建一个方法,允许我传递一个查询和值“在数组中”,该方法将自动为我准备查询。
所以不要为每个INSERT / UPDATE查询编写方法或代码,而不是......
MySqlCommand command = connection.CreateCommand();
command.CommandText = "INSERT INTO mytable(a,b,c,d)VALUES (?, ?, ?, ?)";
command.Parameters.AddWithValue("?", array_val1);
command.Parameters.AddWithValue("?", array_val2);
command.Parameters.AddWithValue("?", array_val3);
command.Parameters.AddWithValue("?", array_val4);
connection.Open();
command.ExecuteNonQuery();
我想有一个方法,我可以传递查询和值,它会自动为我准备该语句。
类似这样的事情
//Call the Method
processQuery("INSERT INTO mytable(a,b,c,d)VALUES (?, ?, ?, ?)", array(1,2,3,4));
//The new Method
public processQuery(string sqlStr, array values){
MySqlCommand command = connection.CreateCommand();
command.CommandText = sqlStr;
command.Parameters.AddWithValue("?", array_val1);
command.Parameters.AddWithValue("?", array_val2);
command.Parameters.AddWithValue("?", array_val3);
....
....
....
....
command.Parameters.AddWithValue("?", array_val_SIZE_OF_ARRAY);
connection.Open();
command.ExecuteNonQuery();
}
答案 0 :(得分:1)
您可以让您的方法接受表名和MySqlParameter列表,然后根据传入的内容制作SQL。
public void ProcessQuery(string tableName, MySqlParameter keyParam, params MySqlParameter[] sqlParams)
{
using(MySqlConnection cn = new MySqlConnection(this.ConnectionString))
using(MySqlCommand cmd = cn.CreateCommand())
{
/*Update Statement*/
//Param1 = @Param1, Param2 = @Param2, @Param3 = @Param3, etc.
string updateParamStr = string.Join(
", ",
sqlParams.Select(sqlParam => string.Format("{0} = {1}", sqlParam.ParameterName.Substring(1), sqlParam.ParameterName)));
//param = @param
string keyMatchStr = string.Format("{0} = {1}",
keyParam.ParameterName.Substring(1),
keyParam.ParameterName);
string updateSql = string.Format("UPDATE {0} SET {1} WHERE {2}",
tableName,
updateParamStr,
keyMatchStr);
/*Insert Statement*/
//produce comma delimited list of param names with leading @ stripped eg. Param1, Param2, Param3
string columnNameStr = string.Join(", ", sqlParams.Select(sqlParam => sqlParam.ParameterName.Substring(1)));
//produce comma delimited list of param eg. @Param1, @Param2, @Param3
string valueParamStr = string.Join(", ", sqlParams.Select(sqlParam => sqlParam.ParameterName));
string insertSql = string.Format("INSERT INTO {0} ({1}) VALUES ({2})",
tableName,
columnNameStr,
valueParamStr);
/*Combined Update and Insert*/
string combinedSql = string.Format("{0} {1} WHERE ROW_COUNT() = 0", updateSql, insertSql);
cmd.CommandText = combinedSql;
cmd.Parameters.Add(keyParam);
cmd.Parameters.AddRange(sqlParams);
cn.Open();
cmd.ExecuteNonQuery();
}
}
生成的SQL会创建一个组合的UPDATE和INSERT语句,如下所示:
UPDATE MyTable SET Col1 = @Col1, Col2 = @Col2 WHERE KeyCol = @KeyCol
INSERT INTO MyTable (Col1, Col2) VALUES (@Col1, @Col2) WHERE ROW_COUNT() = 0
这有效地运行UPDATE,可以更新匹配的行或不进行任何更改。在后一种情况下,ROW_COUNT()将= 0,然后使INSERT语句完成其工作。我们只是在每个语句中利用WHERE子句使事物互相排斥。
然后,您将调用该方法传递MySqlParameter以获取唯一键,然后调用任意数量的MySqlParameter对象。
ProcessQuery(
"MyTable",
new MySqlParameter("@MyKeyColumn", 5)/*unique key column*/,
new MySqlParameter("@SomeColumn", 1),
new MySqlParameter("@SomeOtherColumn", "Some string"));
这样做的好处是,如果您愿意,可以在MySqlParameter中提供数据类型信息,或者您可以使用名称+值对保持简单。这确实需要使用@ParamName语法而不是“?”并且参数名称与目标列匹配,无论如何都是更清晰的IMO。