Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Force Oracle Drop Global Temp Table

Globale temporäre Oracle-Tabellen sind keine vorübergehenden Objekte. Sie sind richtige Heap-Tabellen. Wir erstellen sie einmal und in jeder Sitzung können sie verwenden, um Daten zu speichern, die nur für diese Sitzung sichtbar sind .

Der temporäre Aspekt besteht darin, dass die Daten nicht über eine Transaktion oder eine Sitzung hinaus bestehen bleiben. Das wichtigste Implementierungsdetail besteht darin, dass die Daten in einen temporären Tablespace geschrieben werden, nicht in einen permanenten. Die Daten werden jedoch immer noch auf die Festplatte geschrieben und von ihr gelesen, sodass die Verwendung globaler temporärer Tabellen einen erheblichen Overhead mit sich bringt.

Der Punkt ist, dass wir temporäre Tabellen nicht löschen und neu erstellen sollen. Wenn Sie versuchen, Logik im Stil von SQL Server in Oracle zu portieren, sollten Sie die Verwendung von PL/SQL-Sammlungen in Betracht ziehen, um temporäre Daten im Speicher zu halten. Finde mehr heraus.

Die spezifische Ursache von ORA-14452 ist, dass wir eine globale temporäre Tabelle mit Persistenz im Sitzungsbereich nicht löschen können, wenn sie während der Sitzung Daten enthalten hat. Auch wenn die Tabelle gerade leer ist...

SQL> create global temporary table gtt23 (col1 number)
  2  on commit preserve rows
  3  /

Table created.

SQL> insert into gtt23 values (1);

1 row created.

SQL> commit;

Commit complete.

SQL> delete from gtt23;

1 row deleted.

SQL> commit;

Commit complete.

SQL> drop table gtt23;
drop table gtt23
           *
ERROR at line 1:
ORA-14452: attempt to create, alter or drop an index on temporary table already in use

SQL>

Die Lösung besteht darin, die Sitzung zu beenden und erneut zu verbinden oder (etwas bizarr) die Tabelle abzuschneiden und dann zu löschen.

SQL> truncate table gtt23;

Table truncated.

SQL> drop table gtt23;

Table dropped.

SQL> 

Wenn eine andere Sitzung die globale temporäre Tabelle verwendet - und das ist möglich (daher die global Nomenklatur), dann können Sie die Tabelle nicht löschen, bis alle Sitzungen getrennt werden.

Die wirkliche Lösung besteht also darin, zu lernen, globale temporäre Tabellen richtig zu verwenden:Erstellen Sie spezifische globale temporäre Tabellen, die zu jedem Bericht passen. Oder, wie gesagt, verwenden Sie stattdessen PL/SQL-Sammlungen. Oder lernen Sie einfach, gut abgestimmtes SQL zu schreiben. Oft verwenden wir temporäre Tabellen als Workaround für eine schlecht geschriebene Abfrage, die mit einem besseren Zugriffspfad gespeichert werden könnte.

Nachdem Sie sich Ihren vollständigen Code angesehen haben, erscheint der Ablauf noch bizarrer:

  1. Eine globale temporäre Tabelle löschen und neu erstellen
  2. Temporäre Tabelle füllen
  3. Aus temporärer Tabelle in PL/SQL-Array auswählen
  4. Einfügen in aktuelle Tabelle mit Masseneinfügung aus PL/SQL-Array

Hier gibt es so viel Overhead und verschwendete Aktivitäten. Alles, was Sie tun müssen, ist, die Daten zu übernehmen, die Sie in v2d_temp einfügen und füllen Sie vertical_design direkt aus , idealerweise mit einer INSERT INTO ... SELECT * FROM-Anweisung. Sie benötigen eine gewisse Vorverarbeitung, um ein JSON-Array in eine Abfrage umzuwandeln, aber das ist entweder in Java oder PL/SQL einfach zu erreichen.

Mir scheint sicher, dass globale temporäre Tabellen für Ihr Szenario nicht die richtige Lösung sind.

"unser Chef oder andere Personen beharren darauf, etwas auf ihre Weise zu tun, also können Sie das nicht ändern"

Was Sie haben, ist ein Boss-Problem kein Programmierproblem . Folglich ist es für StackOverflow kein Thema. Aber hier sind trotzdem einige Vorschläge.

Das Wichtigste, woran Sie denken sollten, ist, dass wir nicht über einen Kompromiss bei einer suboptimalen Architektur sprechen:Was Ihr Chef vorschlägt, wird ganz klar nicht funktionieren in einer Mehrbenutzerumgebung. Ihre Optionen sind also:

  1. Ignorieren Sie ORA-14452 Fehler, fahren Sie mit der Produktion fort und verwenden Sie dann die "Aber Sie haben es mir gesagt"-Verteidigung, wenn alles schrecklich schief geht. Dies ist das schwächste Stück.
  2. Verschrotten Sie heimlich die globalen Tabellen und implementieren Sie etwas, das in einem Szenario mit mehreren Benutzern funktioniert. Dies ist ein hohes Risiko, da Sie keine Verteidigung haben, wenn Sie die Implementierung verpfuschen.
  3. Sprechen Sie mit Ihrem Chef. Sagen Sie ihnen, dass Sie auf ORA-14452 stoßen Fehler, sagen Sie, Sie haben einige Nachforschungen angestellt und es scheint ein grundlegendes Problem bei der Verwendung globaler temporärer Tabellen auf diese Weise zu geben, aber offensichtlich haben Sie etwas übersehen. Fragen Sie sie dann, wie sie dieses Problem umgangen haben, wenn sie es zuvor implementiert haben. Dies kann auf verschiedene Arten gehen, vielleicht haben sie eine Problemumgehung, vielleicht erkennen sie, dass dies der falsche Weg ist, globale temporäre Tabellen zu verwenden, vielleicht sagen sie Ihnen, dass Sie sich verirren sollen. In jedem Fall ist dies der beste Ansatz:Sie haben Bedenken auf der entsprechenden Ebene geäußert.

Viel Glück.