1

こんにちは、保険ドメインの小さなアプリケーションを開発しています。プログラムで update ステートメントを使用すると、エラーが発生します。

エラーは net.ucanaccess.jdbc.UcanaccessSQLException: 予期しないトークン: 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);
        }
    }
});
4

1 に答える 1

3

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'

隣接する 2 つの一重引用符はエスケープされた一重引用符として扱われるため、パーサーはリテラル文字列が "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 が埋め込まれたエスケープ文字を探すため)、読みやすくなります。

于 2015-07-15T16:31:42.000 に答える