【问题标题】:Java SQL Query not working with Insert?Java SQL 查询不能与插入一起使用?
【发布时间】:2018-07-28 08:02:12
【问题描述】:

为什么不向表中添加更多数据?代码/查询有什么问题?数据库已连接并与 Select * ... 但是当我尝试使用 Insert into 时,它给出了如下所示的错误,这是为什么呢?我该如何纠正这个错误?

 public void RegisterNewUser(String username, String password, String firstname, String surname, String dateOfBirth, int currentWeight) {

    //This code will connect the database to the java program

    Connection myconObj = null; //allows to connect to database
    Statement mystatObj = null; // create statement (Execute queries)
    ResultSet myresObj = null; // get result
    ResultSetMetaData mymeta = null;

    try {

        String query = "INSERT INTO JACOVANSTRYP.MAINUSERDATA(USERNAME, PASSWORD, FIRSTNAME, LASTNAME, DATEOFBIRTH, CURRENTWEIGHTKG, ACTIVEPOINTS) VALUES(\"" + username + "\", \"" + password + "\", \"" + firstname + "\", \"" + surname + "\",\"" + dateOfBirth + "\", \"" + currentWeight + "0 )";

        myconObj = DriverManager.getConnection("jdbc:derby://localhost:1527/MainUserData", "jacovanstryp", "Eduplex1234");
        mystatObj = myconObj.createStatement();
        Statement add = myconObj.createStatement();
        add.executeUpdate(query);
        mymeta = myresObj.getMetaData();





        System.out.println("User Successfuly created");
    } catch (SQLException e) {
      e.printStackTrace();
    }

这是它给出的错误消息,我试图在没有从另一个类获得的值的情况下执行此操作,即使查询是写在没有外部值的平面字符串中,它仍然会给出相同的错误。

    java.sql.SQLSyntaxErrorException: VALUES clause must contain at least one element. Empty elements are not allowed. 
    at org.apache.derby.client.am.SQLExceptionFactory.getSQLException(Unknown Source)
    at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
    at org.apache.derby.client.am.ClientStatement.executeUpdate(Unknown Source)
    at com.vanstryp.backend.commonMethods.RegisterNewUser(commonMethods.java:143)
    at com.vanstryp.GUI.Secure.Register.jButton1ActionPerformed(Register.java:389)
    at com.vanstryp.GUI.Secure.Register.access$400(Register.java:6)
    at com.vanstryp.GUI.Secure.Register$4.actionPerformed(Register.java:139)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
    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:6533)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    at java.awt.Component.processEvent(Component.java:6298)
    at java.awt.Container.processEvent(Container.java:2236)
    at java.awt.Component.dispatchEventImpl(Component.java:4889)
    at java.awt.Container.dispatchEventImpl(Container.java:2294)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
    at java.awt.Container.dispatchEventImpl(Container.java:2280)
    at java.awt.Window.dispatchEventImpl(Window.java:2746)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: ERROR 42X80: VALUES clause must contain at least one element. Empty elements are not allowed. 
    at org.apache.derby.client.am.ClientStatement.completeSqlca(Unknown Source)
    at org.apache.derby.client.am.ClientStatement.completeExecuteImmediate(Unknown Source)
    at org.apache.derby.client.net.NetStatementReply.parseEXCSQLIMMreply(Unknown Source)
    at org.apache.derby.client.net.NetStatementReply.readExecuteImmediate(Unknown Source)
    at org.apache.derby.client.net.StatementReply.readExecuteImmediate(Unknown Source)
    at org.apache.derby.client.net.NetStatement.readExecuteImmediate_(Unknown Source)
    at org.apache.derby.client.am.ClientStatement.readExecuteImmediate(Unknown Source)
    at org.apache.derby.client.am.ClientStatement.flowExecute(Unknown Source)
    at org.apache.derby.client.am.ClientStatement.executeUpdateX(Unknown Source)
    ... 41 more

【问题讨论】:

  • 使用参数重写
  • 尝试使用准备好的语句并使用执行查询而不是更新
  • 它说executeQuery方法不能用于更新。
  • 你在最后一个零之前缺少一个逗号。

标签: java sql


【解决方案1】:

选择的方法比查询本身有更多的错误。我已经重写了您的代码以使用 PreparedStatement 功能:

public void RegisterNewUser(String username, String password, String firstname, String surname, String dateOfBirth, int currentWeight) {

    //This code will connect the database to the java program

    Connection myconObj = null; //allows to connect to database
    ResultSet myresObj = null; // get result
    ResultSetMetaData mymeta = null;

    try {

        String query = "INSERT INTO JACOVANSTRYP.MAINUSERDATA(USERNAME, PASSWORD, FIRSTNAME, LASTNAME, DATEOFBIRTH, CURRENTWEIGHTKG, ACTIVEPOINTS) VALUES(?,?,?,?,?,?,?)";

        myconObj = DriverManager.getConnection("jdbc:derby://localhost:1527/MainUserData", "jacovanstryp", "Eduplex1234");
        PreparedStatement add = myconObj.prepareStatement(query);
        add.setString(1, username);
        add.setString(2, password);
        add.setString(3, firstname);
        add.setString(4, lastname);
        add.setString(5, dateOfBirth); // might need setDate() depending on your table structure
        add.setString(6, currentWeight);
        add.setString(7, "0");
        add.executeUpdate();
        mymeta = myresObj.getMetaData();
        System.out.println("User Successfuly created");
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

希望对您有所帮助...

@MarkRotteveel 想要解释 OP 代码有什么问题。真的,没什么特别的。它可能会起作用,但在施工中需要更加小心。此外,像 OP 一样构建 SQL 会使他容易受到注入攻击。同样,对于业余项目来说不是问题,但在专业环境中,您不想编写对 SQL 注入开放的代码。

【讨论】:

  • 您能否解释一下原始方法有什么问题。
  • mystatObj = myconObj.createStatement();这一行说它需要将 PreparedStatement 转换为“mystatObj = (PreparedStatement) myconObj.createStatement();”当我这样做时,它返回此错误“线程中的异常“AWT-EventQueue-0”java.lang.ClassCastException:org.apache.derby.client.am.ClientStatement 无法转换为 java.sql.PreparedStatement”知道为什么?
  • 抱歉,@jaco,请取消 mystatObj 行
  • @MarkRotteveel 符合您的要求吗?
  • 我不会以 “真的,没什么特别的。” 开头,因为原始代码中的 SQL 注入是一个巨大的安全漏洞。而且我不会提到它“对业余项目来说不是问题”,因为在业余项目中学到的习惯和技术通常也会在不考虑专业背景的情况下应用。
【解决方案2】:

您为 7 个参数查询插入 6 个参数(检查您的最后一个零)。 你应该这样做:

  "INSERT INTO JACOVANSTRYP.MAINUSERDATA(USERNAME, PASSWORD, FIRSTNAME, LASTNAME, DATEOFBIRTH, CURRENTWEIGHTKG, ACTIVEPOINTS) VALUES(param1, param2, etc)"

参考: How to use java variable to insert values to mysql table?

所以试试这样的:

String query = "INSERT INTO JACOVANSTRYP.MAINUSERDATA(USERNAME, PASSWORD, FIRSTNAME, LASTNAME, DATEOFBIRTH, CURRENTWEIGHTKG, ACTIVEPOINTS) VALUES(\"" + username + "\", \"" + password + "\", \"" + firstname + "\", \"" + surname + "\",\"" + dateOfBirth + "\", \"" + currentWeight + ",0 )";

【讨论】:

  • -1 不建议使用准备好的语句,而是提倡使代码对 SQL 注入开放的不安全方法,并且您的建议甚至不起作用,因为最初的问题在于使用双引号(用于引用对象名称)而不是单引号(用于文字)。
猜你喜欢
  • 1970-01-01
  • 2015-04-10
  • 2018-07-04
  • 1970-01-01
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多