Можно ли использовать прямую вставку пути с JDBC/Java?

У нас есть приложение, написанное на C и Pro*C, которое вставляет данные из файлов журналов в базу данных Oracle 11.2, используя массивы хостов и массовую вставку. Это использует APPEND а также NOLOGGING советы по использованию прямой вставки пути и уменьшению количества повторов. NOLOGGING Это имеет смысл, поскольку это временная промежуточная таблица, и данные могут быть восстановлены из файлов журнала, если это необходимо.

Мы пытаемся воспроизвести эту функциональность в Java, но не смогли использовать прямую вставку пути большого количества записей. Это возможно с Java/JDBC?

Вещи, которые я пробовал и исследовал:

  • Пакетирование JDBC (как стандартное пакетирование, так и расширения Oracle). Этот подход экономит время прохождения туда-обратно, но это незначительно, поскольку приложение находится на той же машине, что и база данных. Это также не использует прямой путь.
  • APPEND_VALUES намек. Это звучит многообещающе, но не имеет особого смысла, так как пакетная обработка JDBC, по-видимому, фактически не выполняет вставку "массива" многих записей.

Из того, что я понимаю, прямая вставка пути поддерживает только синтаксис подзапроса, а не предложение VALUES. Это нельзя использовать, поскольку данные для вставки еще не существуют в базе данных.

Мне не удалось найти ссылки на то, что Java может использовать загрузку стилей массива хоста, которую использует Pro*C.

Кроме того, мы изучаем загрузку внешних таблиц или загрузчик SQL* и ценим, что эти инструменты способны к прямой загрузке пути, но на самом деле вопрос заключается в том, чтобы получить окончательный ответ о том, возможна ли прямая вставка пути из Java. Понимание ограничений Java API полезно не только для этого проекта, но и для будущих.

Итак, чтобы повторить вопрос, есть ли способ, которым я могу использовать прямую вставку пути из Java?

Связанный вопрос:

2 ответа

Я нашел этот ответ:

прямые вставки пути возможны только при вставке в x как сценарий select * from y. Это можно сделать с помощью jdbc, без проблем. Это невозможно сделать с помощью вставки и значений. Это также невозможно сделать, когда база данных находится в режиме принудительного ведения журнала. В большинстве случаев, когда резервная база данных подключена, основная база данных будет находиться в режиме принудительного ведения журнала.

Как упомянул Гэри Майерс, начиная с 11gR2 есть подсказка APPEND_VALUES. Как и в случае со «старой» подсказкой добавления, ее следует использовать только для объемных вставок.

Документация Oracle четко гласит это:

    If you are performing an INSERT with the VALUES clause, specify the APPEND_VALUES hint in 
each INSERT statement immediately after the INSERT keyword. Direct-path INSERT with the VALUES
 clause is best used when there are hundreds of thousands or millions of rows to load. The
  typical usage scenario is for array inserts using OCI. Another usage scenario might be inserts in a FORALL statement in PL/SQL

,

Поэтому ответ на ваш вопрос - подсказка APPEND_VALUES. Я вижу в вашем посте, что вы пробовали, но не можете понять, с какой проблемой вы столкнулись.

Также это утверждение в вашем посте неверно: "Насколько я понимаю, прямая вставка пути поддерживает только синтаксис подзапроса, а не предложение VALUES". Документация Oracle дает этот пример:

Следующий фрагмент кода PL/SQL является примером использования подсказки APPEND_VALUES:

FORALL i IN 1..numrecords
  INSERT /*+ APPEND_VALUES */ INTO orderdata 
  VALUES(ordernum(i), custid(i), orderdate(i),shipmode(i), paymentid(i));
COMMIT;

Ссылка на документацию оракула: http://docs.oracle.com/cd/E11882_01/server.112/e25494/tables004.htm

Образец кода:

dbConnection.setAutoCommit(false);//commit trasaction manually

String insertTableSQL = "INSERT /*+ APPEND_VALUES */ INTO DBUSER"
            + "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) VALUES"
            + "(?,?,?,?)";              
PreparedStatement = dbConnection.prepareStatement(insertTableSQL);

preparedStatement.setInt(1, 101);
preparedStatement.setString(2, "test1");
preparedStatement.setString(3, "system");
preparedStatement.setTimestamp(4, getCurrentTimeStamp());
preparedStatement.addBatch();

preparedStatement.setInt(1, 102);
preparedStatement.setString(2, "test2");
preparedStatement.setString(3, "system");
preparedStatement.setTimestamp(4, getCurrentTimeStamp());
preparedStatement.addBatch();
preparedStatement.executeBatch();

dbConnection.commit();
Другие вопросы по тегам