【问题标题】:I query to get a column default value but ORA-17003 appears我查询以获取列默认值,但出现 ORA-17003
【发布时间】:2019-07-15 09:59:43
【问题描述】:

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

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)

但我无法弄清楚我错过了什么。

编辑:如果我在 mostraDefault 方法的 finally 子句中关闭 rs 和 conn,

错误 SQL 17009:关闭语句 被抛出。

【问题讨论】:

  • 您是否有意不关闭mostraDefault 中的rspsconn?看起来 `Database.nuovaConnessione()§ 可能会从两个调用中为您提供 same 连接对象,对吗?
  • 如果我关闭该资源,则会引发另一个异常:17009 已关闭语句
  • 是的,或者使用 try-with 块;否则你会在某个时候泄漏连接。不过,如果两者使用相同的连接,这只是问题的一部分。
  • 17009 关闭语句被抛出

标签: java sql oracle swing


【解决方案1】:

你真的有两个问题。首先,您没有关闭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();
...

那么这两个 DB 调用根本不会重叠。

但是,再一次,看看 try-with 块,如果你使用的是合适的 Oracle 版本(如果 Spring 对这些感到满意,不知道......)

【讨论】:

  • 我实际上在 insert 方法的 finally 子句中关闭了该对象,但在此处粘贴代码时意外剪切。这实际上有效,但由于某种原因,这会使用“”获得默认值(例如“Nuovo progetto”而不是 Nuovo Progetto),但我修复了这个问题。谢谢
  • 引号包含在data_default 中,因此如果您想像这样使用该数据字典值,您可能需要自己剪掉它们。
猜你喜欢
  • 2021-08-26
  • 2017-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-12
  • 2022-10-13
  • 1970-01-01
相关资源
最近更新 更多