C# 使用OleDbAdaptor和查询参数打开Excel工作表
这是我以前打开excel工作表的方法:C# 使用OleDbAdaptor和查询参数打开Excel工作表,c#,sql,excel,oledb,C#,Sql,Excel,Oledb,这是我以前打开excel工作表的方法: public static System.Data.DataTable GetEntireSheet(string fileName, string sheetName) { string connectionString = GetConnectionString(fileName); System.Data.DataTable excelTable = new System.Data.DataTable(); 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传递给的查询字符串
中的“OleDbDataAdapter.OleDbDataAdapter(字符串,OleDbConnection)”
“ExcelWrapper.GetEntireSheet(字符串,字符串)”可以包含
以下变量的string.Format(CultureInfo.InvariantCulture,
“从[{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);
}
}
但是,它看起来可疑,并且它还生成一个OLEDBE异常:
Microsoft Access数据库引擎找不到对象“?”。
确保对象存在,并拼写其名称和路径
正确命名。如果“?”不是本地对象,请检查网络
连接或联系服务器管理员
使用查询参数调用此函数的正确方法是什么?不能使用参数表示表名(工作表名)。仅当要传递INSERT、UPDATE和in WHERE子句的值时,才使用参数 然而,正如所指出的,通过代码分析工具,您可以使用一个白色的表名列表,用户可以在其中进行选择,而无需键入任何内容 从OLEDB连接中使用,并使用DropDownStyle的DropDownList填充组合
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;
}
使用(OleDbConnection excel\u con=新的OleDbConnection(connectionString))
使用(OleDbCommand cmd=new OleDbCommand())
{
excel_con.Open();
DataTable结果=excel\u con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,null);
var NAME=result.AsEnumerable().Select(x=>x.Field(“TABLE_NAME”).TrimEnd(“$”).ToList();
comboBoxTables.DataSource=名称;
}
现在,您的代码可以使用comboBoxTables中的SelectedItem并使用字符串连接方法,而不会出现Sql注入问题。使用下面给出的代码,即用户显式提供程序声明
public System.Data.DataTable ReadExcel(string fileName, string fileExt, strig SheetName)
{
string conn = string.Empty;
System.Data.DataTable dtexcel = new System.Data.DataTable();
if (fileExt.CompareTo(".xls") == 0)
conn = @"provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";Extended Properties='Excel 8.0;HRD=Yes;IMEX=1';"; //for below excel 2007
else
conn = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties='Excel 12.0;HDR=YES';"; //for above excel 2007
using (OleDbConnection con = new OleDbConnection(conn))
{
try
{
String Query = String.Format("select * from [{0}]",SheetName);
// [sheet1] = [YouerSheetNameinExcelFile]
//OleDbDataAdapter oleAdpt = new OleDbDataAdapter("select * from [sheet1]", con); //here we read data from sheet1
OleDbDataAdapter oleAdpt = new OleDbDataAdapter(Query, con); //here we read data from sheet1 and from specific cell range.
oleAdpt.Fill(dtexcel); //fill excel data into dataTable
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
}
return dtexcel;
}
参数不能用于表示代码分析工具建议避免用户输入的表名。可以使用GetSchema方法检索表名(即工作表名),然后将所有内容放在组合框中,用户只能选择有效的名称。谢谢,但是工作表名来自另一个类,因此不能硬编码。此外,这并没有解决问题的查询参数方面。在这一点上,用户没有关于工作表名称的选择(可能在将来),但我知道您来自哪里,关于“白名单”。我将很快对此进行调查。那么,这是一种例外情况,在这种情况下,您可以抑制警告。代码分析工具不知道您的字符串是否安全。因此,除非您的工具制造商为产品添加更多智能,否则您将被迫抑制或忽略警告。