我需要一个返回列默认值的方法,所以我做了以下方法:

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对那些块满意的话,不知道...)

07-24 22:13