在C#WinForm应用程序中写入数据库时出现问题
本文关键字:问题 数据库 C#WinForm 应用程序 | 更新日期: 2023-09-27 18:20:56
我在专业编程方面相对缺乏经验,但我正在尝试编写一个与MS Access数据库接口的程序。从本质上讲,我在表单中收集信息,并试图在每一个条目的新行中传递信息。我有一个打开的OleDbConnection,我的测试显示我能够看到哪一行将有新条目,但当我点击提交按钮时,catch中没有显示错误,但数据库保持不变。我最初在一个从点击事件调用的方法中有代码,但我只是把代码交给事件处理程序,以验证问题是否与调用有关。
private void btnSubmit_Click(object sender, EventArgs e)
{
if (DBConnection.State.Equals(ConnectionState.Closed))
{
DBConnection.Open();
}
try
{
MessageBox.Show("Save Data at index: " + intRowPosition.ToString());
OleDbCommand OledbInsert = new OleDbCommand("Insert INTO RetentionTable (DateTime,Center,CSP,MemberID,ContractNumber,RetentionType,RetentionTrigger,MemberReason,ActionTaken,Other) VALUES('" + DateTime.Now.ToString() + "','" + GetCenter("") + "','" + GetName("") + "','" + GetMemberID("") + "','" + GetContractNumber("") + "','" + GetType("") + "','" + GetTrigger("") + "','" + GetReason("") + "','" + GetAction("") + "', + GetOther("")," DBConnection);
intRowPosition++;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
MessageBox.Show(ex.StackTrace.ToString());
}
finally
{
RefreshDBConnection();
}
}
任何关于为什么这不是写作的想法都将不胜感激。
上面的代码中有很多问题。
- 首先,应该执行命令,而不是简单地声明(这就是数据库未被修改的原因)
- 其次,在语句中使用保留关键字(因此,即使执行语句,它也会失败并引发异常)
- 第三,连接字符串以构建命令文本。A.非常糟糕的举动会使您的应用程序容易受到SQL注入攻击
- 第四,使用后应关闭连接
让我试着写一个替换代码
string cmdText = "Insert INTO RetentionTable " +
"([DateTime],Center,CSP,MemberID,ContractNumber,RetentionType," +
"RetentionTrigger,MemberReason,ActionTaken,Other) " +
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
using(OleDbConnection cn = new OleDbConnection(conString))
using(OleDbCommand cmd = new OleDbCommand(cmdText, cn))
{
cmd.Parameters.AddWithValue("@p1", DateTime.Now.ToString());
cmd.Parameters.AddWithValue("@p2", GetCenter(""));
cmd.Parameters.AddWithValue("@p3", GetName(""));
cmd.Parameters.AddWithValue("@p4", GetMemberID(""));
cmd.Parameters.AddWithValue("@p5", GetContractNumber(""));
cmd.Parameters.AddWithValue("@p6", GetType(""));
cmd.Parameters.AddWithValue("@p7", GetTrigger(""));
cmd.Parameters.AddWithValue("@p8", GetReason(""));
cmd.Parameters.AddWithValue("@p9", GetAction(""));
cmd.Parameters.AddWithValue("@p10", GetOther(""));
cmd.ExecuteNonQuery();
}
DATETIME是Access中的一个保留关键字,因此,如果要将其用于列名,则需要将其括在方括号中。
字符串串联在MSAccess中是一种糟糕的做法,但它在其他数据库中是一个致命的缺陷,您的代码可以用于Sql注入(在Access中更困难,但并非不可能)。如果像我的例子中那样使用参数化查询,则可以消除Sql注入问题,但也可以让框架代码将正确的值传递给数据库引擎,并使用日期、字符串和小数所需的正确格式。
另一个需要考虑的点是不要有全局OleDbConnection对象,而是在需要时创建、使用和销毁对象。连接池将避免性能问题,当连接因任何原因失败时,您的代码都不会受到内存泄漏的影响
我还想补充一点,您的GetXXXXX方法似乎都返回字符串。请记住,这些方法应该返回与要写入的底层数据库字段兼容的值
这可能是您放入数据库中的值周围的语音标记。试着改成撇号。
无论如何,我强烈建议将最终的SQL存储在一个字符串中,并将其打印到日志文件或屏幕中,然后将其复制到Access SQL编辑器中并尝试运行它。然后,您将看到是否存在错误以及它是什么。