我在尝试将数据写入我的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。 如果需要进一步的信息,我很乐意提供。 如果我的问题伤害了任何感情,请考虑我不是很有经验,因此是宽容的。:)
答案 0 :(得分:2)
转换为英文的错误消息说
Maximum number of open cursors exceeded
问题是你正在泄漏游标。可能发生这种情况的一个地方是内部for
循环。
当身体
if (id_exist == 0) {
未执行,您应该关闭ResultSet
的try / finally永远不会被执行。那会泄漏光标。最终,Oracle不会让你再打开......
我建议您阅读自Java 7以来Java支持的“try with resources”。
它允许您编写易于阅读且不易出错的资源清理代码。
此外,如果您发现有一种方法,其中大部分代码都缩进了9级深度。这应该是一个标志,你需要重构它。说真的,你不需要需要在一个单一的整体方法中完成所有这些工作。首先,重构代码将使您(以及其他所有人)更容易理解。