是否可以使用JDBC/Java直接路径插入?

Bur*_*Ali 7 java bulkinsert jdbc oracle11g direct-path

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

我们试图在Java中复制此功能,但无法使用大量记录的直接路径插入.这可能是Java/JDBC吗?

我尝试和调查过的事情是:

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

据我所知,直接路径插入仅支持子查询语法,而不支持VALUES子句.这不能用作数据库中尚不存在的要插入的数据.

我一直无法找到任何Java能够使用Pro*C使用的主机数组样式加载的引用.

顺便说一句,我们正在调查外部表加载或SQL*加载器,并了解这些工具能够直接路径加载,但这个问题实际上是关于是否可以从Java直接路径插入获得明确的答案.了解Java API的局限性不仅对此项目有用,而且对将来的项目也很有用.

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

相关问题:

Lok*_*esh -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
Run Code Online (Sandbox Code Playgroud)

因此,您的问题的答案是 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;
Run Code Online (Sandbox Code Playgroud)

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();
Run Code Online (Sandbox Code Playgroud)

  • 我已经尝试过了,它不会触发直接路径插入,因为您仍然一次只插入一条记录,而不是一个数组(如 OP 中提到的以及 PL/SQL 示例中所示)。 (3认同)
  • 另外 - “直接加载 INSERT(串行或并行)只能支持 INSERT 语句的 INSERT ... SELECT 语法,而不是 INSERT ... 值语法”,来自 https://docs.oracle.com/cd/ A58617_01/server.804/a58227/ch_dlins.htm (3认同)