0

我有一个我无法弄清楚的问题,我确信这很容易,但我的谷歌搜索和 Stackoverflow 搜索并没有让我到达那里。java文档也没有帮助。我发现了很多人们在 SQL 语句或代码中出现语法错误的问题。我认为我的在代码中。它是关于通过查询从数据库中获取一些信息,用户可以在其中填写自己的搜索信息(数字)。

这是代码:(我已经尝试了多种方法,所以我的代码可能不再是最好的了。另外我是java新手,所以请考虑到这一点。)

    /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dbConnection;

import data.Mail;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import view.SelectionScreenCRA;

/**
 *
 * @author vm
 */
public class dbConnect {

    public static Connection getConnection() {
        String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
        String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\\Users\\Jeroen Veldhuijzen\\locaties.mdb;";
        String username = "";
        String password = "";

        try {
            Class.forName(driver);
            return DriverManager.getConnection(url, "", "");

        } catch (Exception ex) {
            Logger.getLogger(dbConnect.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("\nError: " + ex.toString() + ex.getMessage());

        }
        return null;
    }

    public static ArrayList<dbConnect> executeQuery(int cra) {


         ArrayList<dbConnect> locatie = new ArrayList<dbConnect>();

        Mail mail = new Mail();
        try{
        Connection conn = getConnection();
        PreparedStatement pst = conn.prepareStatement(
                "SELECT Locatiegegevens.[Locatiegegevens], "
                + "Locatiegegevens.[ISP - Straatnaam], "
                + "Locatiegegevens.[ISP - Huisnummer],"
                + " Locatiegegevens.[ISP - Postcode], "
                + "Locatiegegevens.[ISP - Plaatsnaam], "
                + "Locatiegegevens.[G4S - Transportcode] "
                + "FROM Locatiegegevens "
                + "WHERE Locatiegegevens.[Locatiegegevens] = '?';");


        pst.setInt(1, cra);
        pst.execute();

        pst.close();
        conn.close();

        }catch (Exception e){
            System.out.println("ERRROOOOR");

            System.out.println(e.getMessage());
            System.out.println(e.getClass());
            Logger.getLogger(dbConnect.class.getName()).log(Level.SEVERE, null, e);

        }
        return locatie;

    }

}

int cra 将在此处设置:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    dbConnect dbc = new dbConnect();
    dbConnect.executeQuery(Integer.parseInt(getCRA().getText()));        
}

cra 将作为 String 检索,然后在传递给 executeQuery 命令时解析为 int。如果我发出 cra int,它会给我 int 9501,它会在文本框中填写。但是,如果我通过按下按钮 jButton1 来运行查询,则会出现 null 错误:

null

class java.lang.NullPointerException
aug 09, 2012 12:43:04 PM dbConnection.dbConnect executeQuery
SEVERE: null
java.lang.NullPointerException
    at sun.jdbc.odbc.JdbcOdbcPreparedStatement.clearParameter(JdbcOdbcPreparedStatement.java:1022)
    at sun.jdbc.odbc.JdbcOdbcPreparedStatement.setInt(JdbcOdbcPreparedStatement.java:526)
    at dbConnection.dbConnect.executeQuery(dbConnect.java:62)
    at view.SelectionScreenCRA.jButton1ActionPerformed(SelectionScreenCRA.java:502)
    at view.SelectionScreenCRA.access$900(SelectionScreenCRA.java:29)
    at view.SelectionScreenCRA$11.actionPerformed(SelectionScreenCRA.java:333)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6504)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6269)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4860)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4686)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2713)
    at java.awt.Component.dispatchEvent(Component.java:4686)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
    at java.awt.EventQueue.access$000(EventQueue.java:101)
    at java.awt.EventQueue$3.run(EventQueue.java:666)
    at java.awt.EventQueue$3.run(EventQueue.java:664)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:680)
    at java.awt.EventQueue$4.run(EventQueue.java:678)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

有没有人可以指出我正确的方向?

4

2 回答 2

0

Micko 已经确定了问题所在。正如他所说,您永远不应该在查询字符串中的参数占位符 (?) 周围加上引号。不管是什么类型。

这只是为了解释实际发生的事情......以及为什么你会得到 NPE。

如果在参数标记周围加上引号,则实际上是在编写 SQL 字符串。当createPreparedStatment分析您的查询字符串时,它根本找不到任何标记。从句法的角度来看,这没关系1 ......但这意味着查询并不意味着您想要它的意思。

然后它变得有点模糊。NPE 在您尝试set(不存在的)参数 1 时发生。但是如果您查看堆栈跟踪,它实际上是在一个名为clearParameter. 我没有寻找 MS JDBC 驱动程序的源代码,但我的猜测是准备好的语句解析器创建了一个占位符参数数组。但是,如果它没有找到任何东西,它就不会费心分配数组。这通常是无害的......但是如果您随后尝试设置占位符的值,则代码似乎没有正确检查,并且意外生成了 NPE。

无论哪种方式,在这种情况下抛出 NPE 对 JDBC 驱动程序而言都是不良行为。我会称它为Bug!

更新

我在这里找到了源代码,我的假设基本上是正确的……除了这是旧的 Sun 代码,而不是 Microsoft 代码。(从包名中应该很明显......呃!)

问题boundParamsnull。如果您查看第 2727 行,则仅当占位符的数量大于零时才对其进行初始化。漏洞!


1 - 实际上,这是不行的,因为在这种情况下,您很可能会收到 SQL 错误,因为“字符串”与列的类型不匹配。但是当查询到达数据库服务器时执行该分析......对于许多 JDBC 驱动程序,直到您第一次实际执行查询时才会发生这种情况。

于 2013-06-22T01:14:21.847 回答
0

删除参数标记 (?) 周围的引号。也不需要查询字符串末尾的分号:

"WHERE Locatiegegevens.[Locatiegegevens] = ?");
于 2012-08-09T11:44:55.890 回答