问题 是否可以在SQLite查询中参数化表名和列名?


我试图在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个不同的命令,当我需要搜索不同的列名称。

这是什么问题?


7198
2017-11-10 05:48


起源

如果您因为将每个命令绑定到SqliteConnection以及反复构建其参数和CommandText的效率低而无法创建10个不同的命令,那么我只是确保读者知道有替代方法。 SqliteCommand只有一个新的SqliteCommand()的无参数构造函数;并且其Connection属性可在运行时分配。因此,您只需创建并初始化许多命令,然后将其Connection属性分配给在运行时重复创建和处置的SqliteConnection对象。 - Gary Z


答案:


通常,列名(或表名)之类的东西可以  参数化 - 以及有不同指数的事实意味着它会  在内部成为一个不同的计划。所以你将不得不使用串联 -  小心列出已知的列名以阻止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;

14
2017-11-10 05:58





您不能以这种方式使用查询参数 - 以指示列名称。您只能使用它来提供值。

考虑这样的事情:

    SQLiteCommand cmd = new SQLiteCommand(
    "SELECT [ID]" +
        ",[email]" +
        ",[serializedata]" +
        ",[restrictions]" +
    " FROM " + UserTable +
    " WHERE [" + search + "] = @searchparam", SQLConnection);

    cmd.Parameters.Add(new SQLiteParameter("@searchparam"));

如果你控制了这个函数的所有输入,如果它可以由你以外的其他人提供,那么这应该是安全的。但如果 search 来自不受信任的第三方,请务必对价值进行适当的安全检查。


2
2017-11-10 06:00