我在C#/ .net中使用OleDB并且不喜欢oledb使用问号做参数的方式:
using (OleDbConnection sqlConnect = drtevs.GetConnection())
{
OleDbCommand command.CommandText = "UPDATE NAME SET FIRST_NAME = ?, LAST_NAME = ? WHERE ID = ?;";
command.Parameters.Add(new OleDbParameter("@FIRST_NAME", txtFirst));
command.Parameters.Add(new OleDbParameter("@LAST_NAME", txtLast));
command.Parameters.Add(new OleDbParameter("@ID", 12));
command.ExecuteNonQuery();
}
我看到的问题是它们没有命名,因此无法重复使用它们。有没有更好的方法用OleDB做参数?如果有人可以通过以下方式给我代码来执行LINQ-TO-SQL之类的代码:
db.ExecuteQuery("UPDATE NAME SET FIRST_NAME = {0}, LAST_NAME = {1} WHERE ID = {2}", txtFirst, txtLast, 12);
我知道原生SQL .net提供程序已命名参数(例如@FIRST_NAME,@ LAST_NAME),但由于我正在使用SQL Server和Oracle,因此无法选择。
编辑: 我想避免SQL注入和清理我的参数,也能够插入非可序列化的对象,如字节数组。
如果我的姓氏是“'DROP TABLE NAME - ”,那么到目前为止的所有答案都将失败,此外它会对我的数据库造成损害
答案 0 :(得分:3)
如果你想重新使用这个值,而你想要理智的查询,也许是道德等同于:
declare @id int = ?
declare @when datetime = ?
...
// some complex query involving @id and @when
此处?
仅限于顶部,上下文清晰。
答案 1 :(得分:1)
我们可以大多模仿linq-to-sql的行为。来自documentation on the function:
参数在查询文本中使用Console.WriteLine()和String.Format()使用的相同卷曲符号表示。实际上,String.Format()实际上是在您提供的查询字符串上调用的,用生成的参数名称替换花括号参数,例如@ p0,@ p1 ...,@ p(n)。
因此应该可以推导出类似的代码,但有一点需要注意:由于OleDb不支持命名参数,因此未定义多个或无序使用占位符的行为。但我们至少可以得到以下结论:
public void ExecuteQuery(string sql, params object[] parameters)
{
//format the sql string with safe parameter names
var paramNames = new string[parameters.Length];
for (int i = 0; i<parameters.Length; i++)
{
paramNames[i] = "?";
}
sql = string.Format(sql, paramNames);
using (OleDbConnection sqlConnect = drtevs.GetConnection())
{
OleDbCommand command.CommandText = sql;
foreach (int i = 0; i< parameters.Length; i++)
{
command.Parameters.Add(new OleDbParameter("?", parameters[i]));
}
command.ExecuteNonQuery();
}
}
请注意,这对于使用相同占位符两次的查询不起作用,但这是因为OleDb不支持linq-to-sql之类的命名参数。