使用 OleDbAdaptor 和查询参数打开 Excel 工作表

雅米克

这是我以前打开 Excel 表格的方法:

public static System.Data.DataTable GetEntireSheet(string fileName,
    string sheetName)
{
    string connectionString = GetConnectionString(fileName);
    System.Data.DataTable excelTable = new System.Data.DataTable();
    excelTable.Locale = CultureInfo.InvariantCulture;

    using (OleDbConnection connection =
        new OleDbConnection(connectionString))
    {
        using (OleDbDataAdapter adaptor = new OleDbDataAdapter(
            string.Format(CultureInfo.InvariantCulture,
                "Select * from [{0}$]", sheetName),
            connection))
        {
            adaptor.Fill(excelTable);
        }
    }

    return excelTable;
}

这工作正常,但它也会生成代码分析警告:

CA2100 传递给 'ExcelWrapper.GetEntireSheet(string, string)' 中的 'OleDbDataAdapter.OleDbDataAdapter(string, OleDbConnection)' 的查询字符串可以包含以下变量 'string.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}$ ]", sheetName)'。如果这些变量中的任何一个可能来自用户输入,请考虑使用存储过程或参数化 SQL 查询,而不是使用字符串连接构建查询。

sheetname 不是来自用户输入,所以我可以抑制警告,但抑制警告是我尽量避免的一种做法。

我尝试使用以下内容更新该方法:

string query = "SELECT * FROM [?]";
string parameter = string.Format(
    CultureInfo.InvariantCulture, "{0}$", sheetName);
using (OleDbCommand command =
    new OleDbCommand(query, connection))
{
    command.Parameters.Add("?", OleDbType.BSTR).Value =
        parameter;

    using (OleDbDataAdapter adaptor =
        new OleDbDataAdapter(command))
    {
        adaptor.Fill(excelTable);
    }
}

它看起来很可疑,但它还会生成一个 OleDbException:

Microsoft Access 数据库引擎找不到对象“?”。确保该对象存在并且您正确拼写了它的名称和路径名。如果 '?' 不是本地对象,请检查您的网络连接或联系服务器管理员。

使用查询参数调用它的正确方法是什么?

史蒂夫

您不能使用参数来表示表名称(工作表名称)。仅当您想为 INSERT、UPDATE 和 WHERE 子句传递 VALUES 时才使用参数。

但是,正如所指出的,通过您的代码分析工具,您可以使用表名称的白名单,您的用户可以从中进行选择,而无需输入任何内容。

您使用OleDbConnection 中的GetOleDbSchemaTable并使用 DropDownList 的 DropDownStyle 填充组合

using(OleDbConnection excel_con = new OleDbConnection(connectionString))
using(OleDbCommand cmd = new OleDbCommand())
{
    excel_con.Open();
    DataTable result = excel_con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
    var names = result.AsEnumerable().Select(x => x.Field<string>("TABLE_NAME").TrimEnd('$')).ToList();
    comboBoxTables.DataSource = names;
}

现在您的代码可以使用来自 comboBoxTables 的 SelectedItem 并使用字符串连接方法,而不会出现 Sql 注入问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章