2016-08-02 7 views
1

VB программа 6 обрабатывает запись и вставку во временной таблице, то эти записи перемещаются из этой временной таблицы в реальную таблицу какOracle возвращает параллельный запрос до фактической работы заканчивает

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

Временная таблица затем усеченный при записи переносятся

connection.Execute "TRUNCATE TABLE TEMP_TABLE" 

Это работает отлично до тех пор пока я использую PARALLEL подсказку для INSERT запроса. Я получаю эту ошибку на TRUNCATE

ORA-00054: Ресурс занят и приобрести с NOWAIT указанной или тайм-аут истек

Мне кажется, что параллельные запрос возвращает до завершения задания и усечь выдается команда вызывая блокировку.

Я проверил количество записей вставлены, как показано ниже, и обнаружил, что гораздо меньше, чем число записей в таблице временного

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

Есть ли способ ждать INSERT для завершения?

+0

Какая строка подключения? Можете ли вы указать более длительный тайм-аут? – dbmitch

+0

Сделайте 'Delete', а не' Truncate'. Но если это всего лишь временная таблица, зачем вам вообще удалять? 'ON COMMIT {DELETE | PRESERVE} ROWS' уничтожит таблицу после каждого фиксации | сессия. – topshot

+0

@dbmitch Это не о TIMEOUT, но connection.Execute возвращает, что приводит к выполнению следующего запроса, в то время как первый из них все еще находится в процессе – bjan

ответ

0

Предполагается, что вы используете ADO - хотя теперь я замечаю, что у вас нет этого тега в вашем вопросе.

Можете ли вы контролировать состояние соединения с циклом, ожидающим завершения?

Что-то вроде

EDIT - Fix булеву Добавить использовать + вместо "И"

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

Sleep API declare

Edit - Add асинхронная Подсказка/Вариант

Кроме того - это может помочь подключение ADO, чтобы дать ему подсказку, что его работает в асинхронном режиме, путем добавления adAsyncExecute до конца вашей команды выполнить

т.е.. Изменение выполнить команду SQL, чтобы выглядеть как

conn.execute sqlString, recordsaffected, adAsyncExecute 
+0

Нет, он не работает – bjan

+0

Что это значит? У него есть ошибка, она никогда не заканчивается или немедленно выходит из цикла? – dbmitch

+0

Я исправил условие цикла - очевидно, используя И не добавляет бит правильно - оба значения должны быть установлены, поэтому простое их объединение приведет к правильному состоянию – dbmitch

0

Delete может быть медленнее, но Truncate является DDL, который вы не можете запустить в то же время, как DML. Фактически, Truncate требует эксклюзивного доступа к таблице. DML в таблицах будет запрашивать блокировку режима обмена в таблице, что означает, что вы не можете одновременно выполнять DDL против таблицы.

Возможным альтернативным решением могло бы стать использование синонимов.У вас есть таблица А и синоним S Указывая на

create table B as select * from A where 1=0; 
create or replace synonym S for B 

Ваше приложение теперь использует B вместо того, чтобы вы могли делать то, что вы хотите с А.

Делайте это каждый раз, когда вы хотите " truncate "

+0

Я не пробовал это, но что делать, если INSERT и DELETE работают параллельно? УДАЛИТЬ строки, которые еще не были скопированы? – bjan

+0

Если у вас нет критериев, по которым можно выбрать, что удалить, я уверен, что это возможно. Если они из других сессий и еще не совершены, то это не так. Если вам было разрешено делать «усечение», это сделало бы то же самое. В любом случае, если вы пытаетесь добиться большей скорости, параллельно управляя своими утверждениями, вам придется разобраться, как бороться с конфликтами. Таким образом, вы 'INSERT INTO MAIN_TABLE SELECT * FROM TEMP_TABLE WHERE some_key {<, between, ...}' и затем должны иметь то же предложение WHERE, которое вы хотите удалить. – topshot