我试图在SQLite中使用C#执行参数化查询,而我使用的方法就是使用
创建静态命令。 SQLiteCommand cmd = new SQLiteCommand(
"SELECT [ID]" +
",[email]" +
",[serializedata]" +
",[restrictions]" +
" FROM " + UserTable +
" WHERE @search = @searchparam", SQLConnection);
cmd.Parameters.Add(new SQLiteParameter("@searchparam"));
cmd.Parameters.Add(new SQLiteParameter("@search"));
并将其称为:
Command.Parameters["@searchparam"].Value = searchdata;
Command.Parameters["@search"].Value = search;
SQLiteDataAdapter slda = new SQLiteDataAdapter(UserSelectUsernameCommand);
DataSet ds = new DataSet();
slda.Fill(ds);
User[] array = new User[ds.Tables[0].Rows.Count];
int index = 0;
foreach (DataRow row in ds.Tables[0].Rows)
{
array[index] = new User(this, row);
index++;
}
return array;
但我在“'@search'行中出错是不正确的列名”或类似的东西。如果我使用一个常量列名,只使用它的工作参数数据,但我不想创建10个不同的命令,以便我需要搜索不同的列名。
这里有什么问题?
答案 0 :(得分:14)
通常,列名(或表名)之类的内容可以不进行参数化 - 而且有不同索引这一事实意味着 将成为不同的计划内部。所以你必须使用连接 - 但小心地列出已知的列名来阻止sql注入:
SQLiteCommand cmd = new SQLiteCommand(@"
SELECT [ID],[email],[serializedata],[restrictions]
FROM " + whiteListedUserTable + @"
WHERE [" + whiteListedColumnName + @"] = @searchparam", SQLConnection);
cmd.Parameters.Add(new SQLiteParameter("@searchparam"));
...
Command.Parameters["@searchparam"].Value = searchdata;
答案 1 :(得分:2)
您不能以这种方式使用查询参数 - 表示列名。您只能使用它来提供值。
请考虑这样的事情:
SQLiteCommand cmd = new SQLiteCommand(
"SELECT [ID]" +
",[email]" +
",[serializedata]" +
",[restrictions]" +
" FROM " + UserTable +
" WHERE [" + search + "] = @searchparam", SQLConnection);
cmd.Parameters.Add(new SQLiteParameter("@searchparam"));
如果你控制了这个功能的所有输入,如果它可以由你以外的人提供,那么这应该是安全的。但如果search
来自不受信任的第三方,请务必对该值进行适当的安全检查。