我需要一个返回列默认值的方法,所以我做了以下方法:
public String mostraDefault(String column) {
String def = null; //default value
try {
//query to get the def value (tried on oracle and works)
String sql = "Select DATA_DEFAULT from USER_TAB_COLUMNS where TABLE_NAME ='CLASSDIAGRAM' and COLUMN_NAME = '" + column.toUpperCase() + "'";
conn = Database.nuovaConnessione();
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
if (rs.next()) {
def = rs.getString(1);
}
} catch (SQLException ex) {
//Logger.getLogger(ClassDiagram.class.getName()).log(Level.SEVERE, null, ex);
}
return def;
}
该方法由以下方法调用,该方法允许在整个Java Swing GUI的表中插入重排:
public void insertRecord() {
try {
//query to insert
String sql = "INSERT INTO ClassDiagram(Nome) VALUES(?)";
conn = Database.nuovaConnessione();
ps = conn.prepareStatement(sql);
String nome;
//handle default value
if (txtNome.getText().isEmpty()) {
//nome = "Nuovo progetto";
nome = mostraDefault("nome");
System.out.println(nome); //this correctly prints its def val on stout
} else {
nome = txtNome.getText();
}
ps.setString(1, nome);
ps.executeUpdate();
} catch (SQLException e) {
//this gets thrown
JOptionPane.showMessageDialog(this, e.getMessage(), "Errore SQL: " + e.getErrorCode(),
JOptionPane.ERROR_MESSAGE);
} catch (Exception e) {
JOptionPane.showMessageDialog(this, e.getMessage(), "Errore",
JOptionPane.ERROR_MESSAGE);
}
}
但是这种方法抛出
错误SQL 17003:无效的列索引
(抛出SQLException)
但是我无法弄清楚我所缺少的。
编辑:如果我关闭rs和conn在
mostraDefault
方法中的finally子句中,错误SQL 17009:关闭的语句
被抛出。
最佳答案
您确实有两个问题。首先,您不会关闭mostraDefault
方法中的结果集,语句或连接,也不会关闭insertRecord
方法中的语句或连接。 (您可能希望研究try-with块,因此不必显式地进行操作)。
然后,您从对Database.nuovaConnessione()
的两次调用中获得了相同的连接对象。目前,这意味着对mostraDefault
的内部调用将重新放置您已解析的语句,因此,当您绑定值时,该语句不再具有绑定占位符。在mostraDefault
中关闭连接后,绑定将改为看到它认为已关闭的连接。
该部分的解决方法很简单:尽早获得默认值:
public void insertRecord() {
try {
String nome;
//handle default value
if (txtNome.getText().isEmpty()) {
//nome = "Nuovo progetto";
nome = mostraDefault("nome");
System.out.println(nome); //this correctly prints its def val on stout
} else {
nome = txtNome.getText();
}
//query to insert
String sql = "INSERT INTO ClassDiagram(Nome) VALUES(?)";
conn = Database.nuovaConnessione();
ps = conn.prepareStatement(sql);
ps.setString(1, nome);
ps.executeUpdate();
...
然后,两个数据库调用将完全不重叠。
但是,如果您使用的是合适的Oracle版本,请再次研究try-with块(如果Spring对那些块满意的话,不知道...)