在 JAVA 中使用带有 MS Access 2010 数据库的 Update 语句

Posted

技术标签:

【中文标题】在 JAVA 中使用带有 MS Access 2010 数据库的 Update 语句【英文标题】:Using Update statement with MS Access 2010 database in JAVA 【发布时间】:2015-07-15 16:25:14 【问题描述】:

您好,我正在为保险领域开发一个小型应用程序。在我的程序中使用更新语句时出现错误。

错误是 net.ucanaccess.jdbc.UcanaccessSQLException: unexpected token: HALF java.lang.NullPointerException

代码是

btnUpdate = new JButton("UPDATE");
btnUpdate.setMnemonic('U');
btnUpdate.setFont(new Font("Times New Roman", Font.BOLD, 11));
GridBagConstraints gbc_btnUpdate = new GridBagConstraints();
gbc_btnUpdate.insets = new Insets(0, 0, 5, 5);
gbc_btnUpdate.gridx = 3;
gbc_btnUpdate.gridy = 3;
contentPane.add(btnUpdate, gbc_btnUpdate);
btnUpdate.setVisible(false);
btnUpdate.addActionListener(new ActionListener() 
    @Override
    public void actionPerformed(ActionEvent ae) 
        Statement stmt = null;
        ResultSet rset = null;
        Calendar currcal = Calendar.getInstance();
        SimpleDateFormat df;
        df = new SimpleDateFormat("dd-MM-yyyy");
        Date getcurrdate = currcal.getTime();
        String currdate = df.format(getcurrdate);       
        System.out.println(getModeID + "," + getModeofPaymentDescription + "," + getModeofPaymentType + "," + currdate);
        try 
            getModeofPaymentDescription=txt_Mode_Of_Payment_Description.getText().toUpperCase();
            getModeofPaymentType=txt_Mode_Of_Payment_Type.getText().toUpperCase();

            stmt = dbcon.DB_Connection("//F://eclipse_Luna_64_Development_Workspace//ProjectJAVA//LIC_AGENCY_TRACKER//DATABASE//LIC_DATA_TRACKER.accdb").createStatement();
            stmt.executeUpdate("update Mode_Of_Payment_Profile set Mode_Of_Payment_Profile_Type='" + getModeofPaymentType + "'"
                            + "',Mode_Of_Payment_Profile_Description='" + getModeofPaymentDescription + "',Mode_Of_Payment_Profile_Creation_Date='" + currdate + "'"
                            + " where Mode_Of_Payment_Profile_ID='" + getModeID + "'");
         catch (Exception e) 
            //JOptionPane.showMessageDialog(null, "Database Error", "Error Message", JOptionPane.OK_OPTION);
            System.out.println(e);
        

        txt_Mode_Of_Payment_Description.setText("");
        txt_Mode_Of_Payment_Type.setText("");
        btnAdd.setEnabled(true);
        btnModify.setVisible(true);
        btnUpdate.setVisible(false);
        txt_Mode_Of_Payment_Description.requestFocus();

        try 
            stmt.close();
            rset.close();
            dbcon.DB_Connection("//F://eclipse_Luna_64_Development_Workspace//Project JAVA//LIC_AGENCY_TRACKER//DATABASE//LIC_DATA_TRACKER.accdb").close();
         catch (Exception e) 
            System.out.println(e);
        
    
);

【问题讨论】:

【参考方案1】:

您在构建 SQL 字符串的行中有错字。

在您插入 ModeofPaymentType 值的行尾有一个单引号:

"update Mode_Of_Payment_Profile set Mode_Of_Payment_Profile_Type='"+getModeofPaymentType+"'"

下面一行以

开头
+ "',Mode_Of_Payment_Profile_Description='"

导致在您的 modeofPaymentType 值之后插入一个额外的单引号。生成的 SQL 将如下所示

update Mode_Of_Payment_Profile set Mode_Of_Payment_Profile_Type='mode'',Mode_Of_Payment_Profile_Description='FOO'
,Mode_Of_Payment_Profile_Creation_Date='15-07-2015'
where Mode_Of_Payment_Profile_ID='someid'

两个相邻的单引号被视为转义单引号,因此解析器认为文字字符串是“mode',Mode_Of_Payment_Profile_Description=",然后它认为下一个标记是您为 Mode_Of_Payment_Profile_Description 传递的任何值.

如果您要将 java.sql.Statement 的使用替换为 java.sql.PreparedStatement,那么您的更新可能如下所示:

String connectParams = "//F://eclipse_Luna_64_Development_Workspace//Project JAVA//LIC_AGENCY_TRACKER//DATABASE//LIC_DATA_TRACKER.accdb";
Connection connection = dbcon.DB_Connection(connectParams);
PreparedStatement ps = connection.prepareStatement(
    "update Mode_Of_Payment_Profile set" 
    + " Mode_Of_Payment_Profile_Type=?"
    + ", Mode_Of_Payment_Profile_Description=?"
    + ", Mode_Of_Payment_Profile_Creation_Date=?"
    + " where Mode_Of_Payment_Profile_ID=?");
ps.setString(1, getModeofPaymentType);
ps.setString(2, getModeofPaymentDescription);
ps.setString(3, currdate); 
ps.setString(4, getModeID);

这样您就不必做容易出错的事情,例如使用字符串连接插入参数和自己处理引用。它减少了 SQL 注入的机会(因为 PreparedStatement 将寻找嵌入的转义字符)并且更具可读性。

【讨论】:

以上是关于在 JAVA 中使用带有 MS Access 2010 数据库的 Update 语句的主要内容,如果未能解决你的问题,请参考以下文章

带有子查询的 SQL 查询上的 MS Access VBA 运行时错误 3075

使用带有日期的 C# 在 MS Access 97 数据库中清除查询

如何使用 C# 在 MS-Access 中的查询中使用带有通配符的 LIKE 运算符

MS Access 如何使用带有组合框的宏?

如何在ms access数据库c#中插入带有主键的记录

使用宏过滤带有组合框的表单 - MS Access