Kraft Oracle Drop Globale Temporäre Tabelle
In unserem Projekt ich erstellen, eine Globale temporäre Tabelle wird wie diese:
CREATE GLOBAL TEMPORARY TABLE v2dtemp (
id NUMBER,
GOOD_TYPE_GROUP VARCHAR2(250 BYTE),
GOOD_CODE VARCHAR2(50 BYTE),
GOOD_TITLE VARCHAR2(250 BYTE)
)
ON COMMIT PRESERVE ROWS;
aber das problem kommt, wenn ich möchte, dass diese drop-Tabelle.
Oracle wird nicht lassen Sie mich löschen Sie die Tabelle, und er sagt:
ORA-14452: attempt to create, alter or drop an index on temporary table already in use
Habe ich diese Tabelle in einigen Verfahren, aber es kann geändert werden, angewiesen auf andere Berichte. Also sollte ich immer die Tabelle löschen dann sollte ich es neu mit meine benötigten Felder.
Ich habe dies für ein Geschäft Gründen, so ist es nicht möglich für mich zu verwenden, - Tabellen oder andere Dinge. Ich kann nur temp-Tabellen.
Ich habe versucht on commit delete rows, aber wenn ich Anrufe, mein Verfahren zu verwenden, die Daten in dieser Tabelle gibt es keine weiteren Zeilen mehr in der Tabelle und Sie wurden gelöscht.
Jedem hilft, wird sehr geschätzt,
vielen Dank im Voraus
///EDIT
public void saveJSONBatchOpenJobs(final JSONArray array, MtdReport report) {
dropAndCreateTable();
String sql = "INSERT INTO v2d_temp " +
"(ID, KARPARDAZ, GOOD_TYPE_GROUP, GOOD_CODE, GOOD_TITLE, COUNT, "
+ "FACTOR_COUNT, GHABZ_COUNT, DEAL_NO, DEAL_DATE, REQUEST_NO, REQUEST_DATE, "
+ "REQUEST_CLIENT, STATUS, TYPE, MTDREPORT_ID, GEN_SECURITY_DATA_ID) " +
"VALUES (MTD_KARPARDAZ_OPEN_JOBS_SEQ.nextval,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
JSONArray values = array.getJSONArray(i);
if(!values.get(0).equals("null"))
ps.setString(1, values.get(0).toString());
else
ps.setNull(1, Types.VARCHAR);
if(!values.get(1).equals("null"))
ps.setString(2, values.get(1).toString());
else
ps.setNull(2, Types.VARCHAR);
if(!values.get(2).equals("null"))
ps.setString(3, values.get(2).toString());
else
ps.setNull(3, Types.VARCHAR);
if(!values.get(3).equals("null"))
ps.setString(4, values.get(3).toString());
else
ps.setNull(4, Types.VARCHAR);
if(!values.get(4).equals("null"))
ps.setBigDecimal(5, new BigDecimal(values.get(4).toString()));
else
ps.setNull(5, Types.NUMERIC);
if(!values.get(5).equals("null"))
ps.setBigDecimal(6, new BigDecimal(values.get(5).toString()));
else
ps.setNull(6, Types.NUMERIC);
if(!values.get(6).equals("null"))
ps.setBigDecimal(7, new BigDecimal(values.get(6).toString()));
else
ps.setNull(7, Types.NUMERIC);
if(!values.get(7).equals("null"))
ps.setString(8, values.get(7).toString());
else
ps.setNull(8, Types.VARCHAR);
if(!values.get(8).equals("null"))
ps.setDate(9, new Date(new Timestamp(values.getLong(8)).getDateTime()));
else
ps.setNull(9, Types.DATE);
if(!values.get(9).equals("null"))
ps.setString(10, values.get(9).toString());
else
ps.setNull(10, Types.VARCHAR);
if(!values.get(10).equals("null"))
ps.setDate(11, new Date(new Timestamp(values.getLong(8)).getDateTime()));
else
ps.setNull(11, Types.DATE);
if(!values.get(11).equals("null"))
ps.setString(12, values.get(11).toString());
else
ps.setNull(12, Types.VARCHAR);
if(!values.get(12).equals("null"))
ps.setString(13, values.get(12).toString());
else
ps.setNull(13, Types.VARCHAR);
if(!values.get(13).equals("null"))
ps.setString(14, values.get(13).toString());
else
ps.setNull(14, Types.VARCHAR);
if(!values.get(14).equals("null"))
ps.setLong(15, new Long(values.get(14).toString()));
else
ps.setNull(15, Types.NUMERIC);
if(!values.get(15).equals("null"))
ps.setLong(16, new Long(values.get(15).toString()));
else
ps.setNull(16, Types.NUMERIC);
}
@Override
public int getBatchSize() {
return array.size();
}
});
String bulkInsert = "declare "
+ "type array is table of d2v_temp%rowtype;"
+ "t1 array;"
+ "begin "
+ "select * bulk collect into t1 from d2v_temp;"
+ "forall i in t1.first..t1.last "
+ "insert into vertical_design values t1(i);"
+ "end;";
executeSQL(bulkInsert);
}
private void dropAndCreateTable() {
String dropSql = "declare c int;"
+ "begin "
+ "select count(*) into c from user_tables where table_name = upper('v2d_temp');"
+ "if c = 1 then "
+ "truncate table v2d_temp"
+ "drop table v2d_temp;"
+ " end if;"
+ "end;";
executeSQL(dropSql);
String createSql = "CREATE GLOBAL TEMPORARY TABLE v2d_temp (\n"
+ "DEAL_ID NUMBER,\n"
+ "id NUMBER,\n"
+ "karpardaz VARCHAR2(350),\n"
+ "GOOD_TYPE_GROUP VARCHAR2(250 BYTE),\n"
+ "GOOD_CODE VARCHAR2(50 BYTE),\n"
+ "GOOD_TITLE VARCHAR2(250 BYTE),\n"
+ "COUNT NUMBER,\n"
+ "FACTOR_COUNT NUMBER,\n"
+ "GHABZ_COUNT NUMBER,\n"
+ "DEAL_NO VARCHAR2(50 BYTE),\n"
+ "DEAL_DATE DATE,\n"
+ "REQUEST_NO VARCHAR2(50 BYTE),\n"
+ "REQUEST_DATE DATE,\n"
+ "REQUEST_CLIENT VARCHAR2(250 BYTE),\n"
+ "STATUS VARCHAR2(250 BYTE),\n"
+ "TYPE VARCHAR2(250 BYTE),\n"
+ "GEN_SECURITY_DATA_ID NUMBER(10),\n"
+ "MTDREPORT_ID NUMBER\n"
+ ")\n"
+ "ON COMMIT PRESERVE ROWS";
executeSQL(createSql);
}
private void executeSQL(String sql) {
Connection con = null;
try {
con = getConnection();
Statement st = con.createStatement();
st.execute(sql);
} catch (SQLException e) {
e.printStackTrace();
} finally {
if(con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
Mein Chef besteht darauf, mich mit diesem Weg, temp Tabellen und etc. also ich habe keine andere Wahl. Es ist der zweite Tag ich bin auf der Suche nach anderen Möglichkeiten, die Verwendung von temp-Tabellen und die Verwendung der Daten in anderen Abschnitten, können Sie mich zu einigen anderen Arten?
Dann wird Ihr Chef nicht verstehen, wie Oracle funktioniert.
Einen anderen job suchen. Sie werden nicht lernen, etwas von Wert gibt.
vielleicht hast du Recht, aber jetzt, in diesem moment muss ich einen Weg finden, um dieses problem zu lösen, er wird fortbestehen, dass es einen Weg gibt, um dies zu tun, und wenn ich erklären mehr detail, dass es keine Möglichkeit gibt, dies zu tun durch die temp-Tabellen, die ich ihm mehr wütend und er denkt, dass ich nicht weiß, mit was oracle jetzt! Ich erklärte, mehr details in der ersten Antwort die Kommentare, wenn Sie eine Idee haben über, wie kann ich erzwingen, oracle, legen Sie einige temp-Tabelle ohne Berücksichtigung der anderen session-Daten, ich werde so dankbar, wenn Sie teilen es mit mir.
InformationsquelleAutor Naeem Baghi | 2015-09-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Oracle Globale temporäre Tabellen sind nicht transient Objekte. Sie sind ordnungsgemäße heap-Tabellen. Wir erstellen Sie Sie einmal und jede Sitzung Sie verwenden können, um Daten zu speichern, die sichtbar nur zu Sitzung.
Den temporären Aspekt ist, dass die Daten nicht persistent über eine Transaktion oder einer Sitzung. Der Schlüssel detail ist, dass die Daten geschrieben in einen temporären tablespace nicht permanent. Die Daten sind jedoch noch geschrieben - und gelesen von der Festplatte, so gibt es einen bemerkenswerten Aufwand um die Verwendung von globalen temporären Tabellen.
Der Punkt ist, wir sollen nicht zu löschen und neu zu erstellen temporärer Tabellen. Wenn Sie versuchen, auf port, den SQL Server-Stil Logik in der Oracle-sollten Sie PL/SQL-Sammlungen zu pflegen, werden temporäre Daten im Speicher. Finden Sie mehr heraus.
Die spezifische Ursache der
ORA-14452
ist, dass wir nicht fallen eine Globale temporäre Tabelle muss session-scope Beharrlichkeit, wenn es die enthaltenen Daten während der Sitzung. Auch wenn die Tabelle derzeit noch leer...Die Lösung ist, die session zu beenden und neu zu verbinden, oder (etwas Bizarr) zum abschneiden der Tabelle, und legen Sie es.
Wenn eine andere Sitzung verwendet wird die Globale temporäre Tabelle - und das ist möglich (daher die globalen Nomenklatur), dann werden Sie nicht in der Lage, löschen Sie die Tabelle, bis alle Sitzungen trennen.
So die richtige Lösung ist, um zu lernen, Globale temporäre Tabellen richtig: erstellen Sie spezifische Globale temporäre Tabellen, um zu jedem Bericht. Oder, wie ich sage, verwenden Sie PL/SQL-Sammlungen statt. Oder, auch, nur lernen, gut zu schreiben-abgestimmt SQL. Oft verwenden wir temporäre Tabellen als workaround zu einem schlecht geschriebenen Abfrage, die gespeichert werden konnten, mit einem besseren Zugang Weg.
Angeschaut auf Ihre vollständigen code, der flow wirkt noch bizarrer:
Gibt es so viel Aufwand und verschwendet Aktivität hier. Alles, was Sie tun müssen, ist nehmen die Daten, die Sie einfügen in
v2d_temp
und direkt füllenvertical_design
im Idealfall mit einer INSERT INTO ... SELECT * FROM Anweisung. Sie benötigen einige pre-processing") zum konvertieren von JSON-array in einer Abfrage-aber das ist einfach zu erreichen, entweder in Java oder PL/SQL.Scheint es mir sicher zu sein, dass die Globale temporäre Tabellen sind nicht die richtige Lösung für Ihr Szenario.
Was Sie haben, ist ein Chef Problem nicht Programmierung Problem. Deshalb ist es off-topic so weit wie StackOverflow geht. Aber hier sind einige Vorschläge, trotzdem.
Die wichtige Sache zu erinnern ist, dass wir sprechen hier nicht über einen Kompromiss auf einige sub-optimale-Architektur: was Ihr Chef schlägt vor, klar nicht funktionieren in einer multi-user-Umgebung. also, deine Möglichkeiten sind:
ORA-14452
Fehler, gehen in die Produktion und dann mit dem "aber Sie sagte mir," Verteidigung, wenn alles schrecklich schief geht. Dies ist die schwächste Spiel.ORA-14452
Fehler, sagen, Sie haben getan einige Untersuchung und es scheint ein grundlegendes Problem bei der Verwendung globaler temporärer Tabellen in dieser Form aber offensichtlich hast du was übersehen. Dann, Fragen Sie Sie, wie Sie dieses problem umgehen, wenn Sie implementiert haben es vor. Dies kann mehrere Möglichkeiten, vielleicht haben Sie einen workaround, vielleicht werden Sie erkennen, dass dies der falsche Weg, um die Globale temporäre Tabellen, vielleicht werden Sie Ihnen sagen, sich zu verirren. Jede Weise, ist dies der beste Ansatz: man habe Bedenken zu der entsprechenden Ebene.Glück.
Je mehr details Sie liefern, desto weniger erscheint dies wie ein problem, das die Bedürfnisse der globalen temporären Tabellen. Die Tatsache, dass Sie erzählt werden, Sie zu nutzen, indem Sie Ihren Chef bedeutet das ist ein politisches problem, nicht ein technisches und damit außerhalb unserer Verantwortung.
Ich weiß, dass ist ein politisches problem, aber meine Frage ist, eine Antwort zu finden auf die Frage : gibt es eine Möglichkeit zum ablegen einer globalen temporären Tabelle, die abhängig ist von der Sitzung in oracle? Wenn wir so eine Möglichkeit, das zu tun, mein problem ist gelöst.
Natürlich haben Sie sich schon mal in einer ähnlichen situation wie mir, dass Ihr Chef oder andere Personen bestehen, etwas zu tun, die durch Ihre Art und Weise, so dass Sie nicht ändern können, dass man nur einige spezielle Arten oder einige tricks, damit Sie das tun können, was in der schmutzigen Art und Weise!
InformationsquelleAutor APC
Einem anderen Ansatz eine überlegung Wert, hier ist zu überdenken, ob Sie eine temporäre Tabelle.
Es ist sehr üblich, Programmierung unter denjenigen, die den übergang von anderen RDBMS Oracle zu Häufig zu Ihnen, weil Sie nicht verstehen, die Sie verwenden können features wie Common Table Expressions implizit materialise eine temporäre Ergebnismenge, auf die verwiesen werden kann, die in anderen teilen der gleichen Abfrage, und auf anderen Systemen hat es selbstverständlich geworden, das schreiben von Daten in eine Tabelle und wählen Sie dann aus.
Dem scheitern ist in der Regel noch nicht zu verstehen, dass PL/SQL-basierten zeilenweise Verarbeitung ist minderwertig in fast jeder Hinsicht auf SQL-basierter set-Verarbeitung -- langsamer, komplexer code, mehr wortreich, und mehr fehleranfällig-aber Oracle stellt so viele weitere leistungsstarke Funktionen für die SQL-Verarbeitung, die sogar, wenn es erforderlich ist, können in der Regel direkt integriert werden in eine SQL-SELECT-Anweisung trotzdem.
Als Randbemerkung, in 20 Jahren schreiben, Oracle code for reporting-und ETL, ich brauchte nur zu tun, verwenden Sie die Zeile-für-Zeile verarbeiten einmal und nie gebraucht, um die Verwendung einer temporären Tabelle.
InformationsquelleAutor David Aldridge
Töten Sitzungen ist der einzige Weg, das zu umgehen ORA-14452 Fehler. Verwenden Sie die data-dictionary zu finden weitere Sitzungen mit der temporären Tabelle und töten
mit einer Aussage wie
alter system kill session 'sid,seriall#,instance_id';
.Dies ist die "offizielle" Lösung erwähnt, die in der Oracle support-Dokument
, WIE ZUM DIAGNOSTIZIEREN EINES ORA-14452 WÄHREND DROP VON TEMPORÄREN TABELLE (Doc-ID 800506.1). Ich habe erfolgreich mit dieser Methode in der Vergangenheit für einen etwas anderen Grund.
Töten Sitzungen erfordert erhöhte Rechte und kann schwierig sein; es kann verlangen, zu töten, zu warten, und versuchen Sie es erneut mehrmals.
Diese Lösung ist sicherlich eine schlechte Idee für viele Gründe. Bevor Sie diese umsetzen, Sie sollten versuchen, zu nutzen und diese Informationen als Beweis, dass dies
der falsche Weg, es zu tun. Zum Beispiel, "der Oracle-Dokumentation sagt, dass diese Methode erfordert
alter system
Privileg, das ist gefährlich und wirft einigeFragen der Sicherheit...".
Ach ja, das töten von Sitzungen ist sehr gefährlich und kann dazu führen, dass alle Arten von Problemen. Es ist extrem selten, um eine Anwendung zu töten Sitzungen. Es ist der einzige Weg, um diese Arbeit zu machen, aber ich bin nicht wirklich vorschlagen Sie tun. Stattdessen möchten Sie vielleicht, es zu erwähnen, um Ihre DBA; Sie werden wohl darauf bestehen, finden Sie einen anderen Ansatz.
glücklicherweise ist diese Aufgabe von mir, und er teilte es an eine andere person, die er gefunden hat, dass dies nicht zu geschehen, so werden wir diskutieren wieder die Weise ändern, die wir umsetzen wollen, diese Aufgabe
InformationsquelleAutor Jon Heller
Sehen Sie alle Laufenden Sitzungen durch:
Zur Sitzung beenden, haben Sie ein paar Optionen. Der folgende Befehl wartet, bis das aktuelle in-flight-Transaktionen abschließen, die vor dem trennen:
Während der folgende Befehl ist nur wie kill -9; es wischt die O/S-Prozess aus:
Letzteres ist am meisten effizient bei der Tötung der Sitzung, dass Sie verhindert das entfernen einer temporären Tabelle. Allerdings ist mit Vorsicht zu verwenden, da es eine ziemlich brute-force-Funktion. Sobald die Sitzung beendet ist, können Sie entfernen Sie die temporäre Tabelle ohne Fehler.
Lesen Sie mehr über die verschiedenen Möglichkeiten der Tötung einer Sitzung hier (ich bin in keinerlei Verbindung mit dieser website, stieß ich auf es mich, wenn ich hatte ein ähnliches problem an Euch):
https://chandlerdba.wordpress.com/2013/07/25/killing-a-session-dead/
InformationsquelleAutor dearsina