简体   繁体   English

无法在C#WinForm应用程序中写入数据库

[英]Trouble writing to database in C# WinForm Application

I'm relatively inexperienced with professional programming, but I'm trying to write a program that interfaces with a MS Access Database. 我对专业编程相对缺乏经验,但我正在尝试编写一个与MS Access数据库接口的程序。 Essentially I'm gathering information in the form and trying to pass information at a new line for each entry. 基本上我正在收集表单中的信息,并尝试在每个条目的新行传递信息。 I have an open OleDbConnection and my test is showing that I am able to see what row will have the new entry, but when I hit the submit button, there is no error shown in the catch, but the database remains unchanged. 我有一个开放的OleDbConnection,我的测试显示我能够看到哪个行将有新条目,但是当我点击提交按钮时,catch中没有显示错误,但数据库保持不变。 I originally had the code in a method that I called from the click event, but I just brought the code over to the event handler to verify the issue wasn't with the call. 我最初在我从click事件调用的方法中获得了代码,但我只是将代码放到事件处理程序中以验证问题不在于调用。

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();
        }

    }

Any ideas as to why this is not writing would be much appreciated. 关于为什么这不写作的任何想法将非常感激。

There are many problems in your code above. 您的代码中存在许多问题。

  • First, a command should be executed, not simply declared. 首先,应该执行一个命令,而不是简单地声明。 (this is why the database is not being modified) (这就是数据库没有被修改的原因)
  • Second, you use reserved keywords in your statement (so even if you execute your statement, it will fail and throw an exception) 其次,在语句中使用保留关键字(因此即使执行语句,它也会失败并抛出异常)
  • Third, you are concatenating strings to build the command text. 第三,您正在连接字符串以构建命令文本。 A very bad move that would leave your application susceptible to SQL injection attacks 一个非常糟糕的举动会使您的应用程序容易受到SQL注入攻击
  • Fourth, the connection should be closed after usage 第四,连接应在使用后关闭

Let me try to write a replacement code 让我试着写一个替换代码

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();
 }

The DATETIME is a reserved keyword in Access and thus, if you want to use it for your column names then you need to enclose it in square brackets. DATETIME是Access中的保留关键字,因此,如果要将其用于列名,则需要将其括在方括号中。

The string concatenation is a bad practice in MSAccess but it is a fatal flaw in other database where your code could be used for Sql Injections (more difficult in Access but not impossible). 字符串连接在MSAccess中是一种不好的做法,但它是其他数据库中的致命缺陷,其中您的代码可用于Sql注入 (在Access中更难但不是不可能)。 If you use a parameterized query as in my example, you remove the Sql Injection problem, but also you let the framework code to pass the correct value to the database engine with the correct formatting required for dates, strings and decimals. 如果您在我的示例中使用参数化查询,则删除Sql Injection问题,但您还要让框架代码将正确的值传递给数据库引擎,并使用日期,字符串和小数所需的正确格式。

Another point to consider is to not have a global OleDbConnection object, but create, use and destroy the object whenever your need it. 另一个要考虑的问题是没有全局OleDbConnection对象,而是在需要时创建,使用和销毁对象。 The Connection Pooling will avoid performance problems and your code will not suffer from memory leaks when a connection fails for whatever reason 连接池将避免性能问题,并且当连接因任何原因失败时,您的代码不会遭受内存泄漏

I want also add that your GetXXXXX methods seems all to return strings. 我还要补充一点,你的GetXXXXX方法似乎都返回字符串。 Remember that these methods should return values compatible with the underlying database field where you want to write 请记住,这些方法应返回与要写入的基础数据库字段兼容的值

It might be the speechmarks around the values you're putting into the database. 它可能是围绕您放入数据库的值的语音标记。 Try changing to apostrophes. 尝试更改为撇号。

Anyway, I strongly recommend storing the final SQL in a string and printing it to a log file or the screen and then copying that to your Access SQL editor and trying to run it. 无论如何,我强烈建议将最终的SQL存储在一个字符串中,然后将其打印到日志文件或屏幕上,然后将其复制到Access SQL编辑器并尝试运行它。 Then you'll see if there's an error and what it is. 然后你会看到是否有错误,它是什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM