JDBC не возвращает более 2,1 миллиарда записей из SELECT - PullRequest
2 голосов
/ 04 апреля 2019

Я читаю записи из таблицы Oracle через JDBC.Таблица содержит около 2,3 миллиарда записей.JDBC вернул мне только макс.2,1 миллиарда записей.Кажется, что JDBC возвращает максимальное количество, эквивалентное максимальному целому числу (2 147 483 647).Обработка заканчивается без ошибок.

Я использую Oracle 11g (выпуск 2) в сочетании с ojdbc7.Я попробовал некоторые настройки размера выборки (в jdbc или / и в java-коде) - я никогда не получал больше записей, чем максимальный размер целого числа.

Я использую стандартный код Java для чтения из БД.Все сохраненные записи в выходном файле верны.

java.sql.Connection conn_tOracleInput_1 = null;
String driverClass_tOracleInput_1 = "oracle.jdbc.OracleDriver";
java.lang.Class.forName(driverClass_tOracleInput_1);

String url_tOracleInput_1 = "jdbc:oracle:thin:@(description=(address=(protocol=tcp)(host="
                + context.COM_SERVER
                + ")(port="
                + context.COM_PORT
                + "))(connect_data=(service_name="
                + context.COM_SERVICE_NAME + ")))";
String dbUser_tOracleInput_1 = context.COM_LOGIN;
String dbPwd_tOracleInput_1 = context.COM_PASSWORD;
java.util.Properties atnParamsPrope_tOracleInput_1 = new java.util.Properties();
atnParamsPrope_tOracleInput_1.put("user", dbUser_tOracleInput_1);
atnParamsPrope_tOracleInput_1.put("password", dbPwd_tOracleInput_1);

conn_tOracleInput_1 = java.sql.DriverManager.getConnection(url_tOracleInput_1, atnParamsPrope_tOracleInput_1);
java.sql.Statement stmtGetTZ_tOracleInput_1 = conn_tOracleInput_1.createStatement();

/* setting time zone */
java.sql.ResultSet rsGetTZ_tOracleInput_1 = stmtGetTZ_tOracleInput_1.executeQuery("select sessiontimezone from dual");
String sessionTimezone_tOracleInput_1 = java.util.TimeZone.getDefault().getID();
while (rsGetTZ_tOracleInput_1.next()) {
   sessionTimezone_tOracleInput_1 = rsGetTZ_tOracleInput_1.getString(1);
}
((oracle.jdbc.OracleConnection) conn_tOracleInput_1).setSessionTimeZone(sessionTimezone_tOracleInput_1);

java.sql.Statement stmt_tOracleInput_1 = conn_tOracleInput_1.createStatement();
String dbquery_tOracleInput_1 = "SELECT ident, end_date, change_date FROM REPO.EMPLOYEE";

java.sql.ResultSet rs_tOracleInput_1 = null;
try {
  rs_tOracleInput_1 = stmt_tOracleInput_1.executeQuery(dbquery_tOracleInput_1);
            rs_tOracleInput_1.setFetchSize(context.FETCH_SIZE);

String tmpContent_tOracleInput_1 = null;
while (rs_tOracleInput_1.next()) {
  ProdCharValStruct prod_char_val = new ProdCharValStruct();

  if (rs_tOracleInput_1.getObject(1) != null)
    prod_char_val.ident = rs_tOracleInput_1.getBigDecimal(1);
 ....
/* write into file */
}

1 Ответ

4 голосов
/ 04 апреля 2019

32-битные ограничения общие

Java была изобретена еще во времена 32-битных машин . Таким образом, вы найдете много ограничений в библиотеках Java, основанных на 32-разрядных. Как вы упомянули, 32-битный int или Integer в Java ограничен Integer.MAX_VALUE: 2 ^ 31-1 или 2 147 483 647.

Например, посмотрите на JavaDoc для вызова ResultSet::setFetchSize. Этот метод занимает int.

Хотя я еще не нашел конкретной документации, я ожидал бы, что курсор в JDBC будет иметь 32-битное ограничение приблизительно в 2,1 миллиарда строк.

На практике ограничение в 2 миллиарда является разумным. Как изумруджава прокомментировал Вопрос, работа с миллиардами строк одновременно вряд ли будет практичной. Добавьте фильтр к вашему запросу, например предложение WHERE, для работы со значимым подмножеством строк.

...