通过Java写入Oracle数据库,导致ORA-00604和ORA-01000

时间:2017-03-13 13:44:30

标签: java oracle jdbc oracle11g

我在尝试将数据写入我的oracle表时遇到了问题。 所以,我要做的是从TMDB(tmdb.org)接收数据并将其写入Oracle表。

这是我的班级所有魔法发生的地方:

public class Movies3 {

    public void execute_to_db() throws SQLException, ClassNotFoundException, RuntimeException {

        final String url = "jdbc:oracle:thin:@192.168.XXX.XXX:XXX:XXX";
        final String user = "TEST2";
        final String password = "XXX";
        final String table = "TMDB_TEST";

        DatabaseConnect db = new DatabaseConnect();
        QueryCreateTable_Movies createtable = new QueryCreateTable_Movies();

        try {
            db.connect(user, password, url);

            ResultSet tablelike = db.processQuery(
                    "SELECT COUNT(table_name) " + "FROM all_tables " + "WHERE table_name = '" + table + "' ");

            PreparedStatement insert_ps = db.prepareStatement("INSERT INTO " + table + " "
                    + "(TMDB_ID, IMDB_ID, ORIGINAL_TITLE, TITLE_DE, BUDGET, REVENUE, RELEASE_DATE) "
                    + "VALUES (?,?,?,?,?,?,?)");

            int tablelike_int = 0;
            while (tablelike.next())
                tablelike_int = tablelike.getInt(1);

            if (tablelike_int == 0)
                db.processInsert(createtable.create);

            else {


                TmdbMovies movies = new TmdbApi("XXX").getMovies();


                MovieDb latest_movie = movies.getLatestMovie();
                int tmdb_max_id = latest_movie.getId();

                try {



                    int id_exist = 0;


                    for (int i = 1; i < tmdb_max_id; i++) {

                        ResultSet id_existq = db
                                .processQuery("SELECT (tmdb_id) FROM " + table + " WHERE tmdb_id = " + i);
                        while (id_existq.next())
                            id_exist = id_existq.getInt(1);

                        if (id_exist == 0) {

                            try {

                                MovieDb movie_name_en = movies.getMovie(i, "en");
                                MovieDb movie_name_de = movies.getMovie(i, "de");
                                String original_title = movie_name_en.getOriginalTitle();
                                String title_de = movie_name_de.getTitle();
                                String imdb_id = movie_name_en.getImdbID();
                                int budget_en = (int) movie_name_en.getBudget();
                                int revenue_en = (int) movie_name_en.getRevenue();
                                String release_date_en = movie_name_en.getReleaseDate();

                                insert_ps.setInt(1, i);
                                insert_ps.setString(2, imdb_id);
                                insert_ps.setString(3, original_title);
                                insert_ps.setString(4, title_de);
                                insert_ps.setInt(5, budget_en);
                                insert_ps.setInt(6, revenue_en);
                                insert_ps.setString(7, release_date_en);

                                insert_ps.executeUpdate();

                                /** Start Output **/

                                double percent = (i * 100) / tmdb_max_id;

                                StringBuilder string = new StringBuilder(140);
                                int percent_int = (int) percent;
                                long total = (long) tmdb_max_id;
                                long current = (long) i;
                                string.append('\r').append(String.join("",
                                        Collections.nCopies(percent_int == 0 ? 2 : 2 - (int) (Math.log10(percent_int)),
                                                " ")))
                                        .append(String.format(" %d%% [", percent_int))
                                        .append(String.join("", Collections.nCopies((percent_int / 2), "=")))
                                        .append('>')
                                        .append(String.join("",
                                                Collections.nCopies((100 / 2) - (percent_int / 2), " ")))
                                        .append(']')
                                        .append(String.join("",
                                                Collections.nCopies(
                                                        (int) (Math.log10(total)) - (int) (Math.log10(current)), " ")))
                                        .append(String.format(" %d/%d | TMDB_ID: %d | Movie: %s", current, total, i,
                                                original_title));

                                System.out.flush();
                                System.out.print(string);

                                /** End Output **/

                                i++;

                                tmdb_max_id = latest_movie.getId();

                            } catch (RuntimeException e) {

                                continue;
                            } catch (SQLException sqle) {
                                System.err.println(sqle + " SQL ERROR at movie with ID" + i);
                                throw sqle;
                            } finally {
                                id_existq.close();
                                insert_ps.close();
                                tablelike.close();
                            }

                        } else
                            i++;

                    }

                } catch (SQLException sqle2) {
                    throw sqle2;
                } catch (RuntimeException e2) {
                    throw e2;
                } finally {

                    insert_ps.close();
                    tablelike.close();
                }
            }

            db.disconnect();
        } catch (SQLException sqle_con) {
            throw sqle_con;

        }

        catch (ClassNotFoundException clnf) {
            throw clnf;

        } finally {


        }
    }

}

执行时,我会收到ORA-00604和ORA-01000。

Exception in thread "main" java.sql.SQLException: ORA-00604: Fehler auf rekursiver SQL-Ebene 1
ORA-01000: Maximale Anzahl offener Cursor überschritten
ORA-00604: Fehler auf rekursiver SQL-Ebene 1
ORA-01000: Maximale Anzahl offener Cursor überschritten
ORA-01000: Maximale Anzahl offener Cursor überschritten

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:951)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:513)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:227)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
    at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:195)
    at oracle.jdbc.driver.T4CStatement.executeForDescribe(T4CStatement.java:876)
    at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1175)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1296)
    at oracle.jdbc.driver.OracleStatement.executeQuery(OracleStatement.java:1498)
    at oracle.jdbc.driver.OracleStatementWrapper.executeQuery(OracleStatementWrapper.java:406)
    at database.DatabaseConnect.processQuery(DatabaseConnect.java:31)
    at tmdb_api_to_db.Movies3.execute_to_db(Movies3.java:75)
    at tmdb_api_to_db.Main.main(Main.java:22)

我很确定,问题的出现是因为我对那些try-catch-finally结构产生了谬误 - 特别是在关闭我的陈述时 - 但是找不到我的错误而我只是觉得像狗一样追尾...

我在Java 8和Oracle 11g上使用Eclipse Neon2。 如果需要进一步的信息,我很乐意提供。 如果我的问题伤害了任何感情,请考虑我不是很有经验,因此是宽容的。:)

1 个答案:

答案 0 :(得分:2)

转换为英文的错误消息说

Maximum number of open cursors exceeded

问题是你正在泄漏游标。可能发生这种情况的一个地方是内部for循环。

当身体

if (id_exist == 0) {

未执行,您应该关闭ResultSet的try / finally永远不会被执行。那会泄漏光标。最终,Oracle不会让你再打开......

我建议您阅读自Java 7以来Java支持的“try with resources”。

它允许您编写易于阅读且不易出错的资源清理代码。

此外,如果您发现有一种方法,其中大部分代码都缩进了9级深度。这应该是一个标志,你需要重构它。说真的,你不需要需要在一个单一的整体方法中完成所有这些工作。首先,重构代码将使您(以及其他所有人)更容易理解。