Globale tijdelijke tabellen van Oracle zijn geen tijdelijke objecten. Het zijn echte stapeltafels. We maken ze eenmalig en elke sessie kan ze gebruiken om gegevens op te slaan die alleen zichtbaar zijn voor die sessie .
Het tijdelijke aspect is dat de gegevens niet blijvend zijn na één transactie of één sessie. Het belangrijkste implementatiedetail is dat de gegevens naar een tijdelijke tabelruimte worden geschreven en niet naar een permanente. De gegevens worden echter nog steeds geschreven naar - en gelezen van - schijf, dus er is een aanzienlijke overhead voor het gebruik van globale tijdelijke tabellen.
Het punt is dat het niet de bedoeling is dat we tijdelijke tabellen laten vallen en opnieuw maken. Als u logica in SQL Server-stijl naar Oracle probeert te porten, kunt u overwegen om PL/SQL-verzamelingen te gebruiken om tijdelijke gegevens in het geheugen te bewaren. Meer te weten komen.
De specifieke oorzaak van ORA-14452
is dat we een globale tijdelijke tabel met persistentie van het sessiebereik niet kunnen verwijderen als deze gegevens bevat tijdens de sessie. Zelfs als de tafel momenteel leeg is...
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>
De oplossing is om de sessie te beëindigen en opnieuw verbinding te maken, of (enigszins bizar) om de tabel af te kappen en vervolgens te laten vallen.
SQL> truncate table gtt23;
Table truncated.
SQL> drop table gtt23;
Table dropped.
SQL>
Als een andere sessie de globale tijdelijke tabel gebruikt - en dat is mogelijk (vandaar de globale nomenclatuur) dan kunt u de tafel pas laten vallen nadat alle sessies zijn verbroken.
De echte oplossing is dus om te leren globale tijdelijke tabellen op de juiste manier te gebruiken:maak specifieke globale tijdelijke tabellen die bij elk rapport passen. Of, zoals ik al zei, gebruik in plaats daarvan PL/SQL-verzamelingen. Of, zelfs, leer gewoon goed afgestemde SQL te schrijven. Vaak gebruiken we tijdelijke tabellen als een tijdelijke oplossing voor een slecht geschreven query die met een beter toegangspad zou kunnen worden opgeslagen.
Na je volledige code te hebben bekeken, lijkt de stroom nog bizarder:
- Een globale tijdelijke tabel verwijderen en opnieuw maken
- Tijdelijke tabel vullen
- Selecteer uit tijdelijke tabel in PL/SQL-array
- Invoegen in werkelijke tabel met bulk-insert uit PL/SQL-array
Er is hier zoveel overhead en verspilde activiteit. Het enige dat u hoeft te doen, is de gegevens die u invoegt in v2d_temp
en direct vertical_design
. invullen , idealiter met een INSERT INTO ... SELECT * FROM-instructie. Je hebt wat voorbewerking nodig om een JSON-array om te zetten in een query, maar dat is eenvoudig te realiseren in Java of PL/SQL.
Het lijkt me zeker dat globale tijdelijke tabellen niet de juiste oplossing zijn voor jouw scenario.
"onze baas of andere personen volharden om iets op hun manier te doen, dus daar kun je niets aan veranderen"
Wat je hebt is een baasprobleem geen Programmeerprobleem . Daarom is het off-topic voor zover StackOverflow gaat. Maar hier zijn toch enkele suggesties.
Het belangrijkste om te onthouden is dat we het niet hebben over een compromis over een suboptimale architectuur:wat je baas voorstelt, zal duidelijk niet werken in een omgeving met meerdere gebruikers. dus uw opties zijn:
- Negeer de
ORA-14452
fout, ga dan in productie en gebruik dan de "maar je zei me dat" verdediging als het allemaal vreselijk mis gaat. Dit is het zwakste spel. - Vervuil de globale tabellen heimelijk en implementeer iets dat werkt in een scenario met meerdere gebruikers. Dit is een groot risico omdat je geen verdediging hebt als je de implementatie verknoeit.
- Praat met je baas. Vertel hen dat je de
ORA-14452
. tegenkomt fout, stel dat je wat onderzoek hebt gedaan en dat het een fundamenteel probleem lijkt met het gebruik van globale tijdelijke tabellen op deze manier, maar je hebt duidelijk iets over het hoofd gezien. Vraag hen vervolgens hoe ze dit probleem hebben opgelost als ze het eerder hebben geïmplementeerd. Dit kan verschillende kanten op, misschien hebben ze een oplossing, misschien beseffen ze dat dit de verkeerde manier is om globale tijdelijke tabellen te gebruiken, misschien zullen ze je vertellen dat je moet verdwalen. Hoe dan ook, dit is de beste aanpak:je hebt je zorgen op het juiste niveau gebracht.
Veel succes.