第一个准备好的语句只执行[关闭]
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 atint custNum = rs.getInt("CUST_NUM");
行和方法的调用。看来我的 netbeans 不支持rs.getInt();
。是吗?
嗨。现在可以了,谢谢!但是仍然没有任何东西插入我的事务表中。
sql3 部分可能应该在 if (rs.next())
内,因为它使用 custNum。
看来问题是我的 Orders 表中的外键约束。它会引发一个错误。它说没有 ORA-02291: 违反完整性约束-找不到父键。父键已经具有与外键相同的值。我可能稍后会修复它,但感谢您的帮助!以上是关于第一个准备好的语句只执行[关闭]的主要内容,如果未能解决你的问题,请参考以下文章