为什么我继续在ResultSet上进行异常非法操作?
以下是代码:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/*
* SearchParts.java
*
* Created on 08-Mar-2010, 12:14:31
*/
package garits;
import java.sql.*;
import javax.swing.*;
/**
*
* @author Deniz
*/
public class SearchParts extends javax.swing.JFrame {
/** Creates new form SearchParts */
public SearchParts() {
initComponents();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
if (!jTextField1.getText().equals("")) {
String result = "";
int Partnumber = Integer.parseInt(jTextField1.getText());
DB db = new DB();
try {
db.connect();
String query = "Select * from Stock Where Part_no =" + "'" + jTextField1.getText() + "'";
ResultSet rs = db.execSQL(query);
if (rs.equals(null)) {
PartNotFound nf = new PartNotFound();
nf.setVisible(true);
} else {
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
int RowCount = 0;
for (int i = 1; i < numberOfColumns; i++) {
rs.getString(i);
result += i + "/n";
}
if (!result.equals("")) {
Receptionist_FranchiseePartFound part = new Receptionist_FranchiseePartFound();
part.setVisible(true);
while (rs.next()) {
RowCount++;
}
part.getTable().addRowSelectionInterval(0, RowCount);
} else {
PartNotFound nf = new PartNotFound();
}
}
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(jButton1, "More information needed for search", "Error Message", JOptionPane.ERROR_MESSAGE);
}
} else if (!jTextField2.getText().equals("")) {
String result = "";
DB db = new DB();
try {
db.connect();
String query = "Select * from Stock Where Part_name =" + "'" + jTextField2.getText() + "'";
ResultSet rs = db.execSQL(query);
if (rs.equals(null)) {
PartNotFound nf = new PartNotFound();
nf.setVisible(true);
} else {
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
int RowCount = 0;
for (int i = 1; i < numberOfColumns; i++) {
rs.getString(i);
result += i + "/n";
}
// Receptionist_FranchiseePartFound part = new Receptionist_FranchiseePartFound();
// part.setVisible(true);
if (!result.equals("")) {
Receptionist_FranchiseePartFound part = new Receptionist_FranchiseePartFound();
part.setVisible(true);
while (rs.next()) {
RowCount++;
}
part.getTable().addRowSelectionInterval(0, RowCount);
} else {
PartNotFound nf = new PartNotFound();
nf.setVisible(true);
}
}
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(jButton1, "More information needed for search", "Error Message", JOptionPane.ERROR_MESSAGE);
}
} else if (jTextField1.getText().equals("") && jTextField2.getText().equals("")) {
String result = "";
DB db = new DB();
try {
db.connect();
String query = "Select * from Stock Where Manufacturer =" + "'" + jTextField3.getText() + "'AND Vehicle_type ='" + jTextField4.getText() + "'";
ResultSet rs = db.execSQL(query);
if (rs.equals(null)) {
PartNotFound nf = new PartNotFound();
nf.setVisible(true);
}
else{
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
int RowCount = 0;
for (int i = 1; i < numberOfColumns; i++) {
rs.getString(i);
result += i + "/n";
}
// Receptionist_FranchiseePartFound part = new Receptionist_FranchiseePartFound();
// part.setVisible(true);
if (!result.equals("")) {
Receptionist_FranchiseePartFound part = new Receptionist_FranchiseePartFound();
part.setVisible(true);
while (rs.next()) {
RowCount++;
}
part.getTable().addRowSelectionInterval(0, RowCount);
} else {
PartNotFound nf = new PartNotFound();
nf.setVisible(true);
}
}
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(jButton1, "More information needed for search", "Error Message", JOptionPane.ERROR_MESSAGE);
}
} else if (jTextField3.getText().equals("") || jTextField4.getText().equals("")) {
JOptionPane.showMessageDialog(jButton1, "More information needed for search", "Error Message", JOptionPane.ERROR_MESSAGE);
}
}
/**
* @param args the command line arguments
*/
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JLabel jLabel8;
private javax.swing.JTextField jTextField1;
private javax.swing.JTextField jTextField2;
private javax.swing.JTextField jTextField3;
private javax.swing.JTextField jTextField4;
// End of variables declaration
}
答案 0 :(得分:2)
我看到了一些事情
第一个rs永远不会为空。如果没有行,则rs.next()将返回false
ResultSet在第一行之前开始。你需要调用rs.next()来移动到第一行,如上所述,如果没有行,它将返回false。
使用ResultSet的典型模式是......
while (rs.next())
{
rs.getXXX();
}
完成后,ResultSet应始终为close()d,否则可能会泄漏数据库资源。这也适用于Connection,Statement,PreparedStatement,因此请检查其他类中的数据库代码。
循环遍历列元数据时,您需要执行此操作..
for(int i = 1; i&lt; = numberOfColumns; i ++){ }
注意&lt; =而不是&lt;。正确地发现JDBC列索引从1开始。
请参阅:Spring docs
答案 1 :(得分:1)
如果rs
为空,则rs.equals(null)
会抛出NullPointerException
而不是返回false
。然而,如果这不是您的例外,那么问题就在于其他地方。
答案 2 :(得分:1)
在访问ResultSet之前,您总是需要在ResultSet上调用next()。如果不是,则指针指向第一行之前的行。你可以在你的代码中使用while循环执行此操作,但有些地方你不这样做会产生错误:
for (int i = 1; i < numberOfColumns; i++) {
rs.getString(i);
result += i + "/n";
}
哦,正如另一张海报所提到的,你不会将结果分配给变量,所以rs.getString(i)调用没有效果。但这可能是你的错误来源。
答案 3 :(得分:1)
另外,请查看DB类的execSQL(查询)方法的javadoc /代码。通常,ResultSet永远不会为null,例如就像你使用PreparedStatement.executeQuery时一样。但是,请检查该execSQL方法以验证它是否将返回null ResultSet。
答案 4 :(得分:0)
删除以下行,它没有用处。 它试图从ResultSet中获取列值但是你还没有滚动到第一行
rs.getString(i);
答案 5 :(得分:0)
有几个人在代码中指出了你的一些问题。您的例外原因是因为您没有使用rs.next()
前进到第一行。如果您希望您的SQL语句只检索一行,那么您可能应该将rs.equals(null)
语句更改为:
if (!rs.next()) {
...code here to set not found...
} else {
...code here to retrieve the columns...
}
以下是其他一些提示。在检索列的代码中,rs.getString(i)
的使用没有做任何事情,result
变量只是用“/ n”累积列号(不是换行符;可能应该是“\ n”)。所以该部分内的循环可能应该变成:
for (int i = 1; i <= numberOfColumns; i++) {
result += rs.getString(i) + "\n";
}
但是连接到不可变的String
并不好,并且可能导致大量连接的执行缓慢。请改用StringBuilder
并将其初始化为合理的大小,如下所示:
StringBuilder sb = new StringBuilder(256);
for (int i = 1; i <= numberOfColumns; i++) {
sb.append(rs.getString(i)).append("\n");
}
result = sb.toString();
稍后你循环遍历结果集,所以在通过列的循环中你是否试图从元数据中获取列名?在那种情况下:
StringBuilder sb = new StringBuilder(256);
for (int i = 1; i <= numberOfColumns; i++) {
sb.append(rsmd.getColumnName(i)).append("\n");
}
result = sb.toString();
但是因为你需要检查第一行,所以下一个循环不会正确计算行数,所以你需要调整它,也许(并且不需要在那时检查result
因为它保证不再是空字符串,因为表中必须至少有一列:
do {
RowCount++; // recommend using rowCount.
} while (rs.next());
最后,你使用result
做什么?似乎这仅用于确定结果中是否存在某些列。如果这就是全部,那么你可以消除大部分代码。对于你实际拥有的东西(我不知道这是否是你的意图),这可以简化为(在其他地方,如果你进行数据库交互):
DB db = new DB();
try {
db.connect();
String query = "select count(1) from Stock where Part_name =" + ...;
ResultSet rs = db.execSQL(query);
if (!rs.next()) {
PartNotFound nf = ...;
nf.setVisible(true);
} else {
Receptionist_FranchiseePartFound part = new Receptionist_FranchiseePartFound();
part.setVisible(true);
rowCount = rs.getInt(1);
part.getTable().addRowSelectionInterval(0, rowCount);
}
} catch (Exception e) {
...error handling with stack trace/JOptionPane...
}
请注意,如果您只是在行数之后,那么最好让数据库引擎为您执行此操作 - 循环结果行只是为了计算它们也意味着必须将所有数据发送到您的应用程序。相反,如果您只使用聚合函数,那么数据库只需要向您的应用程序发送单个行和列。