我正在设计一个从现有MS Access数据库中提取资产信息的C#应用程序。
string conn = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=O:\IT\IT Hardware\HWInv.accdb";
string dbcmd = "SELECT tblInvCategory.Category, tblInvManufacturer.Manufacturer, tblInvModel.Model, tblInvMaster.SerialNumber, tblInvMaster.InvNumber, tblInvMaster.InvNumberExternal, tblInvCompany.CompanyName, tblInvCustomer.CustomerName, tblInvLocation.Location, tblInvMaster.OfficeNumber, tblInvTechs.TechName, tblInvMaster.TechDate, tblInvMaster.UpdatedBy, tblInvMaster.UpdatedDate, tblInvMaster.DeployDate, tblInvMaster.RetirePlanned, tblInvMaster.Status, tblInvMaster.PONumber, tblInvMaster.Notes, tblInvMaster.Audited FROM tblInvTechs INNER JOIN (tblInvModel INNER JOIN (tblInvManufacturer INNER JOIN (tblInvLocation INNER JOIN (tblInvCustomer INNER JOIN (tblInvCompany INNER JOIN (tblInvCategory INNER JOIN tblInvMaster ON tblInvCategory.CategoryID = tblInvMaster.CategoryID) ON tblInvCompany.CompanyID = tblInvMaster.CompanyID) ON tblInvCustomer.CustomerID = tblInvMaster.CustomerID) ON tblInvLocation.LocationID = tblInvMaster.LocationID) ON tblInvManufacturer.ManufacturerID = tblInvMaster.ManufacturerID) ON tblInvModel.ModelID = tblInvMaster.ModelID) ON tblInvTechs.TechID = tblInvMaster.TechID WHERE (((tblInvCustomer.CustomerName)="+ CustomerName + "))";
OleDbConnection con = new OleDbConnection(conn);
OleDbCommand cmd = new OleDbCommand(dbcmd, con);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataTable CustAssets = new DataTable();
da.Fill(CustAssets);
dataGridView1.DataSource = CustAssets;
我在MS Access中为本地MS Access表单存在一个现有查询:
SELECT tblInvCategory.Category, tblInvManufacturer.Manufacturer, tblInvModel.Model, tblInvMaster.SerialNumber, tblInvMaster.InvNumber, tblInvMaster.InvNumberExternal, tblInvCompany.CompanyName, tblInvCustomer.CustomerName, tblInvLocation.Location, tblInvMaster.OfficeNumber, tblInvTechs.TechName, tblInvMaster.TechDate, tblInvMaster.UpdatedBy, tblInvMaster.UpdatedDate, tblInvMaster.DeployDate, tblInvMaster.RetirePlanned, tblInvMaster.Status, tblInvMaster.PONumber, tblInvMaster.Notes, tblInvMaster.Audited
FROM tblInvTechs INNER JOIN (tblInvModel INNER JOIN (tblInvManufacturer INNER JOIN (tblInvLocation INNER JOIN (tblInvCustomer INNER JOIN (tblInvCompany INNER JOIN (tblInvCategory INNER JOIN tblInvMaster ON tblInvCategory.CategoryID = tblInvMaster.CategoryID) ON tblInvCompany.CompanyID = tblInvMaster.CompanyID) ON tblInvCustomer.CustomerID = tblInvMaster.CustomerID) ON tblInvLocation.LocationID = tblInvMaster.LocationID) ON tblInvManufacturer.ManufacturerID = tblInvMaster.ManufacturerID) ON tblInvModel.ModelID = tblInvMaster.ModelID) ON tblInvTechs.TechID = tblInvMaster.TechID
WHERE (((tblInvCustomer.CustomerName)=[Forms]![frmInvSelectCustomerName]![CustomerName]));
如上所述插入SQL命令失败。可变客户名称用于从Access数据库中提取该用户的那些记录,但在编译和运行时失败。
调用堆栈输出这是Text Visualizer:
查询表达式中的语法错误(缺少运算符)'(((tblInvCustomer.CustomerName)= Joe Smith))'。
看来我的问题出在WHERE声明中。
非常感谢任何帮助。
谢谢,
答案 0 :(得分:1)
如果您使用参数化查询,则可以避免此类问题
出现错误的原因是,如果CustomerName
字段是一个字符串,则条件中使用的每个值都应该用单引号括起来。
但是,手动设置引号对于可能的Sql注入是危险的,如果用作值的字符串本身包含单引号,则可能导致其他语法错误。
使用参数化查询可以避免所有这些
string dbcmd = "SELECT ...... " & _
"WHERE (((tblInvCustomer.CustomerName)=?))";
然后
using(OleDbConnection con = new OleDbConnection(conn))
using(OleDbCommand cmd = new OleDbCommand(dbcmd, con))
using(OleDbDataAdapter da = new OleDbDataAdapter(cmd))
{
cmd.Parameters.AddWithValue("@p1", CustomerName);
DataTable CustAssets = new DataTable();
da.Fill(CustAssets);
dataGridView1.DataSource = CustAssets;
}
答案 1 :(得分:0)