我们有一个用C和Pro * C编写的应用程序,它使用主机阵列和批量插入将日志文件中的数据插入到Oracle 11.2数据库中。这使用APPEND
和NOLOGGING
提示来利用直接路径插入并减少重做生成的数量。 NOLOGGING
对此有意义,因为它是一个临时的临时表,如果需要,可以从日志文件中恢复数据。
我们试图在Java中复制此功能,但无法使用大量记录的直接路径插入。这可能是Java / JDBC吗?
我尝试和调查过的事情是:
APPEND_VALUES
提示。这听起来很有希望,但没有道理,因为JDBC批处理实际上并没有实际执行许多记录的“数组”插入。根据我的理解,直接路径插入仅支持the subquery syntax and not the VALUES clause。这不能用,因为要插入的数据尚未存在于数据库中。
我一直无法找到任何对Java能够使用Pro * C使用的主机数组样式加载的引用。
顺便说一下,我们正在研究外部表加载或SQL *加载器,并且意识到这些工具能够直接加载路径,但这个问题实际上是关于是否可以从Java直接插入路径获得明确的答案。了解Java API的局限性不仅对此项目有用,而且对将来的项目也很有用。
所以重申一下这个问题,有没有办法可以利用Java中的直接路径插入?
相关问题:
答案 0 :(得分:0)
我找到了this answer:
直接路径插入只能在插入到 x 中作为 select * from y 方案。这可以使用jdbc来完成,没问题。这不能通过插入和值来完成。当数据库处于强制日志记录模式时,这也无法完成。大多数情况下,当连接备用数据库时,主数据库将处于强制日志记录模式。
正如 Gary Myers 所提到的,从 11gR2 开始就有了 APPEND_VALUES 提示。与“旧”附加提示一样,它只能用于批量插入。
答案 1 :(得分:-1)
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();