第一个准备好的语句只执行[关闭]

Posted

技术标签:

【中文标题】第一个准备好的语句只执行[关闭]【英文标题】:The first prepared statement only executes [closed] 【发布时间】:2015-12-31 02:36:21 【问题描述】:

我在另一个论坛上询问过我的代码,但出现了一个新问题。 第一个准备好的语句只执行。我尝试交换 CUSTOMER 表和 ORDERS 表的准备语句的位置。当CUSTOMER 表准备语句位于第一个位置时,它可以工作,但如果我将它交换到ORDERS 表,它就不起作用,反之亦然。所以这意味着只有第一个准备好的语句执行。 这是我程序的逻辑:here。

我的代码:

payment = Integer.parseInt(custPaymentTextField.getText());
        try
            if(payment>=total)
                change = payment - total;
                JOptionPane.showMessageDialog(this, "Thank you for shopping! Your change is "+change, "Exiting", JOptionPane.INFORMATION_MESSAGE);
                Connection conn = null;
                PreparedStatement pstmt = null;
                PreparedStatement pstmt2 = null;
                PreparedStatement pstmt3 = null;
                String URL = "jdbc:oracle:thin:@VAIO:49160:xe";
                String USER = "mariel";
                String PASS = "1234";

                try 
                     Class.forName("oracle.jdbc.driver.OracleDriver");
                    try 
                        String name = nameTextField.getText();
                        String address = addressTextField.getText();
                        int contact = Integer.parseInt(contactTextField.getText());
                        conn = DriverManager.getConnection(URL, USER, PASS);

                        String sql2 = "INSERT INTO CUSTOMER " + 
                                "VALUES(CustNumSeq.NEXTVAL, ?, ?, ?)";
                        String generatedColumns[] = "CUST_NUM";
                        pstmt2 = conn.prepareStatement(sql2, generatedColumns);
                        pstmt2.setString(1, name);
                        pstmt2.setString(2, address);
                        pstmt2.setInt(3, contact);
                        pstmt2.executeUpdate();
                        ResultSet rs = pstmt2.getGeneratedKeys();
                        custNum = rs.getInt("CUST_NUM");

                        for(int index=0;index<add.itemNum.length;index++)
                            String sql = "INSERT INTO ORDERS "+
                                    "VALUES(OrderNumSeq.NEXTVAL, ?, ?)";    
                            pstmt = conn.prepareStatement(sql);
                            pstmt.setInt(1,add.itemNum[index]);
                            pstmt.setInt(2, add.quantity[index]);

                            pstmt.executeUpdate();
                        

                        creditCard = Integer.parseInt(creditCardTextField.getText());
                        String sql3 = "INSERT INTO TRANSACTION " + 
                            "VALUES(TransNumSeq.NEXTVAL, ?, ?, ?, ?, ?)";
                        pstmt3 = conn.prepareStatement(sql3);
                        pstmt3.setInt(1, custNum);
                        pstmt3.setInt(2, payment);
                        pstmt3.setString(3, payment_desc);
                        pstmt3.setInt(4, creditCard);
                        pstmt3.setInt(5, change);

                     
                    catch (SQLException ex) 
                    
                    catch(NumberFormatException a)
                        JOptionPane.showMessageDialog(this, "Invalid input", "Error!", JOptionPane.ERROR_MESSAGE);
                    
                
                catch(NumberFormatException a)
                    JOptionPane.showMessageDialog(this, "Invalid input", "Error!", JOptionPane.ERROR_MESSAGE);
                
                finally
                    try
                       if(pstmt!=null)
                          pstmt.close();
                    
                    catch(SQLException se2)
                    
                    try
                       if(pstmt2!=null)
                          pstmt2.close();
                    
                    catch(SQLException se2)
                    
                    try
                       if(pstmt3!=null)
                          pstmt3.close();
                    
                    catch(SQLException se2)
                    
                    try
                       if(conn!=null)
                       conn.close();
                    
                    catch(SQLException se)
                    
                    
            
            else
                JOptionPane.showMessageDialog(this, "Your payment is not enough. Please try again!", "Error!", JOptionPane.ERROR_MESSAGE);
        
        catch(NumberFormatException a)
            JOptionPane.showMessageDialog(this, "Invalid input", "Error!", JOptionPane.ERROR_MESSAGE);
        
        catch(ClassNotFoundException ex) 
            System.out.println("Error: unable to load driver class!");
            System.exit(1);
        

错误信息:

java.sql.SQLException: Unsupported feature
at oracle.jdbc.driver.OracleReturnResultSet.findColumn(OracleReturnResultSet.java:95)
at oracle.jdbc.driver.GeneratedResultSet.getInt(GeneratedResultSet.java:1350)
at FinishTransaction.actionPerformed(FinishTransaction.java:156)
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:6516)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6281)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4872)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4698)
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:2719)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:747)
at java.awt.EventQueue.access$300(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:706)
at java.awt.EventQueue$3.run(EventQueue.java:704)
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:720)
at java.awt.EventQueue$4.run(EventQueue.java:718)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:717)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

这是错误消息指向的行:custNum = rs.getInt("CUST_NUM");

【问题讨论】:

吃异常(捕获并丢弃它们而不留下痕迹)是一个非常糟糕的主意,你怎么知道出了什么问题?由于缺少错误消息或堆栈跟踪而投票关闭。 如果您尝试诊断错误,明确忽略错误通常是个坏主意... 我添加了 printStackTrace();生病添加错误消息 【参考方案1】:

应该做如下的事情:

try-with-resources 建议始终关闭 ResultSet 必须先调用/下一个才能获取列值(错误) 必须调用executeUpdate 我会为表 TRANSACTION 选择其他名称,虽然没有错误,但是关键字 将 GUI 访问与业务逻辑分开,这样您就可以编写文本代码(单元测试)。 代替add 中的并行数组,创建一个包含字段的类的数组。

因此

void f(int payment, int total, String name, String address, int contact, int creditCard) throws SQLException 
    if (payment >= total) 
        int change = payment - total;
        JOptionPane.showMessageDialog(null, "Thank you for shopping! Your change is " + change, "Exiting", JOptionPane.INFORMATION_MESSAGE);
        String URL = "jdbc:oracle:thin:@VAIO:49160:xe";
        String USER = "mariel";
        String PASS = "1234";

        // No longer needed in JDBC4: Class.forName("oracle.jdbc.driver.OracleDriver");
        try (Connection conn = DriverManager.getConnection(URL, USER, PASS)) 

            String sql2 = "INSERT INTO CUSTOMER "
                    + "VALUES(CustNumSeq.NEXTVAL, ?, ?, ?)";
            String generatedColumns[] = "CUST_NUM";
            try (PreparedStatement pstmt2 = conn.prepareStatement(sql2, generatedColumns)) 
                pstmt2.setString(1, name);
                pstmt2.setString(2, address);
                pstmt2.setInt(3, contact);
                pstmt2.executeUpdate();
                try (ResultSet rs = pstmt2.getGeneratedKeys()) 
                    if (rs.next()) 
                        int custNum = rs.getInt("CUST_NUM");

                        String sql = "INSERT INTO ORDERS "
                                + "VALUES(OrderNumSeq.NEXTVAL, ?, ?)";
                        try (PreparedStatement pstmt = conn.prepareStatement(sql)) 
                            for (int index = 0; index < add.itemNum.length; index++) 
                                pstmt.setInt(1, add.itemNum[index]);
                                pstmt.setInt(2, add.quantity[index]);

                                pstmt.executeUpdate();
                            
                        
                    

                    String sql3 = "INSERT INTO TRANSACTION "
                            + "VALUES(TransNumSeq.NEXTVAL, ?, ?, ?, ?, ?)";
                    try (PreparedStatement pstmt3 = conn.prepareStatement(sql3)) 
                        pstmt3.setInt(1, custNum);
                        pstmt3.setInt(2, payment);
                        pstmt3.setString(3, payment_desc);
                        pstmt3.setInt(4, creditCard);
                        pstmt3.setInt(5, change);
                        pstmt3.executeUpdate();
                    

                
            
        
    

【讨论】:

它抛出 java.sql.SQLException: Unsupported feature at int custNum = rs.getInt("CUST_NUM"); 行和方法的调用。看来我的 netbeans 不支持rs.getInt();。是吗? 嗨。现在可以了,谢谢!但是仍然没有任何东西插入我的事务表中。 sql3 部分可能应该在 if (rs.next()) 内,因为它使用 custNum。 看来问题是我的 Orders 表中的外键约束。它会引发一个错误。它说没有 ORA-02291: 违反完整性约束-找不到父键。父键已经具有与外键相同的值。我可能稍后会修复它,但感谢您的帮助!

以上是关于第一个准备好的语句只执行[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

休眠和准备好的语句

java准备好的语句

C中的第一个可执行语句

单例连接 + 单例准备好的语句

准备好的语句以及连接池

准备好的语句参数问题