11

我们有一个用 C 和 Pro*C 编写的应用程序,它使用主机阵列和批量插入将日志文件中的数据插入到 Oracle 11.2 数据库中。这使用APPENDNOLOGGING提示来利用直接路径插入并减少生成的重做量。NOLOGGING这很有意义,因为它是一个临时的临时表,如果需要,可以从日志文件中恢复数据。

我们正在尝试在 Java 中复制此功能,但无法使用直接路径插入大量记录。这对 Java/JDBC 可行吗?

我尝试和调查的事情是:

  • JDBC 批处理(标准批处理和Oracle 的扩展)。这种方法节省了往返时间,但这可以忽略不计,因为应用程序与数据库位于同一台机器上。它也不使用直接路径。
  • APPEND_VALUES提示。这听起来很有希望,但意义不大,因为 JDBC 批处理似乎并没有实际执行许多记录的“数组”插入。

据我了解,直接路径插入仅支持子查询语法,不支持 VALUES 子句。这不能使用,因为要插入的数据在数据库中尚不存在。

我一直找不到任何关于 Java 能够使用 Pro*C 使用的主机数组样式加载的参考。

顺便说一句,我们正在研究外部表加载或 SQL*loader 并欣赏这些工具能够直接加载路径,但这个问题实际上是关于是否甚至可以从 Java 中获得直接路径插入的明确答案。了解 Java API 的局限性不仅对本项目有用,对未来的项目也有用。

所以重申这个问题,有没有办法可以利用 Java 的直接路径插入?

相关问题:

4

2 回答 2

0

我找到了这个答案

直接路径插入只能在作为 select * from y 场景的插入 x 中进行。这可以使用jdbc来完成,没问题。这不能通过插入和值来完成。当数据库处于强制记录模式时,这也无法完成。大多数情况下,当备用数据库处于连接状态时,主数据库将处于强制日志记录模式。

正如 Gary Myers 所提到的,从 11gR2 开始就有 APPEND_VALUES 提示。与“旧”附加提示一样,它只能用于批量插入。

于 2020-12-22T20:17:06.650 回答
-2

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;

oracle 文档链接: http: //docs.oracle.com/cd/E11882_01/server.112/e25494/tables004.htm#i1009100

示例代码:

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();
于 2013-06-24T16:23:13.510 回答