Oracle并行查询在实际作业完成之前返回

时间:2016-08-02 12:07:26

标签: oracle oracle11g vb6 ado

VB 6程序正在处理记录并插入临时表,然后将这些记录从此临时表移动到实际表中

connection.Execute "INSERT INTO MAIN_TABLE SELECT * FROM TEMP_TABLE"

移动记录时会截断临时表

connection.Execute "TRUNCATE TABLE TEMP_TABLE"

这很好用,直到我使用PARALLEL提示进行INSERT查询。我在TRUNCATE

上收到此错误
  

ORA-00054:资源繁忙,并在指定NOWAIT或超时时获取   过期

在我看来,并行查询在完成作业之前返回,并且发出TRUNCATE命令导致锁定。

我检查了下面插入的记录数,发现它远远小于临时表中的记录数

connection.Execute "INSERT /*+ PARALLEL */ INTO MAIN_TABLE SELECT * FROM TEMP_TABLE", recordsAffected

有没有办法等待INSERT完成?

2 个答案:

答案 0 :(得分:0)

  

这假设你正在使用ADO - 虽然我现在注意到你没有   你问题中的那个标签。

您是否可以通过循环等待执行完成来监控连接状态?

这样的东西
  

编辑 - 修正布尔值添加使用+而不是“AND”

While Conn.State = (adStateOpen + adStateExecuting)
   DoEvents
   Sleep 500 ' uses Sleep API command to delay 1/2 second
Wend

Sleep API declare

  

编辑 - 添加Asynch提示/选项

此外 - 它可能有助于ADO连接通过将adAsyncExecute添加到执行命令的结尾来提示其异步运行

即。将execute sql命令更改为

conn.execute sqlString, recordsaffected, adAsyncExecute

答案 1 :(得分:0)

Delete可能会慢一些,但Truncate是DDL,您无法与DML同时运行。实际上,Truncate需要对表进行独占访问。表上的DML将在表上请求共享模式锁定,这意味着您不能同时对表执行DDL。

可能的替代解决方案是使用同义词。你有桌子A. 和指向A

的同义词S.
create table B as select * from A where 1=0; 
create or replace synonym S for B

您的应用现在使用B代替A,因此您可以使用A执行您想要的操作。

每次想要“截断”时都这样做