2016-08-02 41 views
1

A VB 6 Programm Datensätze verarbeitet und in einer temporären Tabelle eingefügt, dann werden diese Datensätze aus dieser temporären Tabelle alsOracle parallele Abfrage zurückkehrt, bevor die eigentlichen Job beendet

zu tatsächlichem Tisch bewegen
connection.Execute "INSERT INTO MAIN_TABLE SELECT * FROM TEMP_TABLE" 

Die temporäre Tabelle wird dann abgeschnitten, wenn Datensätze verschoben werden

connection.Execute "TRUNCATE TABLE TEMP_TABLE" 

Das funktioniert gut, bis ich PARALLEL-Hinweis für INSERT-Abfrage verwenden. Ich erhalte diesen Fehler auf TRUNCATE

ORA-00054: resource busy und erwerben mit NOWAIT angegeben oder Timeout abgelaufen

Es sieht für mich, dass parallele Abfrage zurückgibt, bevor der Auftrag abgeschlossen und TRUNCATE-Befehl ausgegeben wird verursacht die Sperre.

überprüfte ich die Anzahl der Datensätze, wie unten eingefügt und festgestellt, dass es weit weniger als die Anzahl der Datensätze in temporärer Tabelle

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

Gibt es eine Möglichkeit zu warten, INSERT abgeschlossen ist?

+0

Was ist Ihre Verbindungszeichenfolge? Können Sie ein längeres Zeitlimit angeben? – dbmitch

+0

Tun Sie ein 'Delete' anstelle von' Truncate'. Aber wenn dies nur eine temporäre Tabelle ist, warum müssen Sie überhaupt löschen? 'ON COMMIT {DELETE | PRESERVE} ROWS 'löscht die Tabelle nach jedem Commit | Session. – topshot

+0

@dbmitch Es geht nicht um TIMEOUT, aber connection.Execute gibt zurück, was bewirkt, dass die nächste Abfrage ausgeführt wird, während die erste noch bearbeitet wird – bjan

Antwort

0

Das setzt voraus, dass Sie ADO verwenden - obwohl ich jetzt bemerke, dass Sie dieses Tag in Ihrer Frage nicht haben.

Können Sie den Verbindungsstatus mit einer Schleife überwachen, die darauf wartet, dass die Ausführung beendet wird?

So etwas wie

EDIT - Fix Boolean Add + verwenden anstelle von "AND"

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

Sleep API declare

Bearbeiten - In Asynch Hint/Option

Auch - es könnte die ADO-Verbindung helfen, ihm einen Hinweis zu geben, dass seine asynchron ausgeführt wird, indem die adAsyncExecute Hinzufügen Befehl Ihres ausführen

dh zu beenden. Ändern Sie den SQL-Befehl ausführen, um wie

conn.execute sqlString, recordsaffected, adAsyncExecute 
+0

Nein, es funktioniert nicht – bjan

+0

Was bedeutet das? Es hat einen Fehler, es endet nie oder es beendet Schleife sofort? – dbmitch

+0

Ich reparierte die Schleifenbedingung - anscheinend benutzt AND nicht die Bits richtig - beide Werte müssen gesetzt werden, also addiert einfach sie zusammen, wird die richtige Bedingung ergeben – dbmitch

0

Delete kann langsamer sein, aber Truncate ist DDL, die Sie nicht zur gleichen Zeit wie DML laufen kann. In der Tat erfordert Truncate exklusiven Zugriff auf die Tabelle. DML für Tabellen fordert eine Freigabe-Modussperre für die Tabelle an, was bedeutet, dass Sie DDL nicht gleichzeitig gegen die Tabelle ausführen können.

Eine mögliche alternative Lösung wäre die Verwendung von Synonymen.Sie haben Ihre Tabelle A und ein Synonym S zeigt auf eine

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

Ihre App jetzt nutzt B statt A, so können Sie tun, was Sie mit A. wollen

Tun Sie dies jedes Mal, wenn Sie wollen " Abschneiden "

+0

Ich habe das nicht versucht, aber was, wenn INSERT und DELETE parallel laufen? löscht es nicht die Zeilen, die noch nicht kopiert wurden? – bjan

+0

Wenn Sie keine Kriterien haben, um auszuwählen, was gelöscht werden soll, bin ich sicher, dass es möglich ist. Wenn sie von anderen Sitzungen stammen und noch nicht festgeschrieben sind, dann würde das nicht funktionieren. Wenn Sie "abschneiden" dürfen, würde es das Gleiche tun. Wie auch immer, wenn Sie versuchen, mehr Geschwindigkeit zu erreichen, indem Sie Ihre Anweisungen parallel ausführen, müssen Sie herausfinden, wie Sie mit den Konflikten umgehen. Also fügen Sie in MAIN_TABLE SELECT * FROM TEMP_TABLE WHERE some_key {<, between, ...} 'ein und haben dann die selbe' WHERE' -Klausel für Ihre Löschung. – topshot