我想在用户输入的数据库中插入新行,我使用C#和sql insert语法。我的问题是当我运行一个程序所有字段完全填写除了文本值(产品的名称),填写另一个数字(价格)我检查语法和代码,但它永远不会工作。
public DataBaseManager (string DataBaseFilename)
{
strFileName = DataBaseFilename;
strFileNamenopath = System.IO.Path.GetFileName(strFileName);
strAccessConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + System.IO.Path.GetFullPath(strFileName).Replace(System.IO.Path.GetFileName(strFileName), "") + "; Extended Properties=dBase III;Mode=ReadWrite";
conn = new OleDbConnection(strAccessConn);
conn.Open();
}
public void AddData(string Column, string value)
{
try
{
int i = 0;
char[] delimiterChars = { ','};
queryCutting = @"INSERT INTO [" + strFileNamenopath + "] ( " + Column + " ) VALUES ( " + value + " )";
OleDbCommand cmd = new OleDbCommand(queryCutting, conn);
string[] _valseperated = value.Split(delimiterChars);
string[] _columnsbase = Column.Split(delimiterChars);
foreach (string str in _columnsbase )
{
cmd.Parameters.AddWithValue(str,SqlDbType.VarChar).Value = _valseperated[i];
i++;
}
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
private void AddnewCode_Buttion_Click(object sender, RoutedEventArgs e)
{
_productBase.AddData("code, pv1, achat, designat", "123456789" + ", " + Textbox_Achat.Text + ", " + Textbox_Achat.Text +", " + Produitsnom_TextBox.Text);
}
列的值表示数据库中的列名,值是文本框的值。
Column = "code, pv1, achat, designat";
Value = "123456789, 10, 10, Productname";
queryCutting的值
queryCutting = "INSERT INTO [produits.dbf] ( code, pv1, achat, designat ) VALUES ( 123456789, 540, 120, NewProduct)"
我想我已经理解了你的问题。您可以直接在查询文本中设置Value字符串,以便获得此结果
"INSERT INTO [theFolderName] (code, pv1, achat, designat)
VALUES ( 123456789, 10, 10, Productname )";
前三个值被接受为数字字段的正确值,并且没有考虑这些字段的参数,但是当解析器到达ProductName“value”时,它不能用作值,因为它不是内部引号。因此它认为它是一个参数并搜索Parameters集合。因为OleDb参数是位置参数,所以它接受第一个参数并将其值传递给OleDbCommand。第一个参数是代码。
这应该可以解决问题。不要给出参数名称(OleDb不关心),让OleDbCommand使用预期的确切顺序给出的完整参数集
public void AddData(string Column, string value)
{
try
{
char[] delimiterChars = { ','};
// Query text is incomplete, we complete it inside the loop
queryCutting = @"INSERT INTO [" + strFileNamenopath + @"]
( " + Column + " ) VALUES ( ";
// The query and the connection will be set after the loop
OleDbCommand cmd = new OleDbCommand();
string[] _valseperated = value.Split(delimiterChars);
string[] _columnsbase = Column.Split(delimiterChars);
foreach (string str in _columnsbase )
{
// The second parameter in AddWithValue is the Value not the type.
cmd.Parameters.AddWithValue(str, _valseperated[i]);
// Add a placeholder for each parameter
queryCutting += "?,";
}
// Remove the ending colon an close the paren on the query text
queryCutting = queryCutting.Substring(queryCutting.Length-1) + ")";
cmd.CommandText = queryCutting;
cmd.Connection = conn;
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
请注意,此代码不能解决您的Sql Injection问题。您应该绝对确定您的用户既不键入文件名/文件夹也不键入列的名称,并从列入白名单的值集中选择这些值
我通过在这样的引号之间添加insering Produits nom_TextBox.Text解决了这个问题
_productBase.AddData("code, designat ,pv1, achat", "123456789" + ", " + "' " +Produitsnom_TextBox.Text + "'" + ", " + Vente_TextBox.Text + ", " + Textbox_Achat.Text );
我也删除了参数部分。
public void AddData(string Column, string value)
{
try
{
int i = -1;
char[] delimiterChars = { ',' };
queryCutting = @"INSERT INTO [" + strFileNamenopath + "] ( " + Column + " ) VALUES ( " + value + " )";
OleDbCommand cmd = new OleDbCommand(queryCutting, conn);
MessageBox.Show(queryCutting);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}