Oracle globala temporära tabeller är inte övergående objekt. De är ordentliga högbord. Vi skapar dem en gång och valfri session kan använda dem för att lagra data som endast är synlig för den sessionen .
Den tillfälliga aspekten är att data inte är beständiga efter en transaktion eller en session. Den viktigaste implementeringsdetaljen är att data skrivs till ett temporärt tabellutrymme, inte ett permanent. Data skrivs dock fortfarande till - och läses från - disk, så det finns en anmärkningsvärd overhead för användningen av globala temporära tabeller.
Poängen är att vi inte ska släppa och återskapa tillfälliga tabeller. Om du försöker porta SQL Server-logik till Oracle bör du överväga att använda PL/SQL-samlingar för att behålla temporär data i minnet. Få reda på mer.
Den specifika orsaken till ORA-14452
är att vi inte kan släppa en global temporär tabell som har sessionsomfångsbeständighet om den har innehållit data under sessionen. Även om tabellen för närvarande är tom...
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>
Lösningen är att avsluta sessionen och återansluta, eller (lite bisarrt) att trunkera tabellen och sedan släppa den.
SQL> truncate table gtt23;
Table truncated.
SQL> drop table gtt23;
Table dropped.
SQL>
Om någon annan session använder den globala temporära tabellen - och det är möjligt (därav den globala nomenklatur) så kommer du inte att kunna släppa tabellen förrän alla sessioner kopplas bort.
Så den verkliga lösningen är att lära sig att använda globala temporära tabeller på rätt sätt:skapa specifika globala temporära tabeller som matchar varje rapport. Eller, som jag säger, använd PL/SQL-samlingar istället. Eller till och med bara lära dig att skriva välinställd SQL. Ofta använder vi tillfälliga tabeller som en lösning på en dåligt skriven fråga som kan sparas med en bättre åtkomstväg.
Efter att ha tittat på din fullständiga kod, verkar flödet ännu mer bisarrt:
- Släpp och återskapa en global temporär tabell
- Fyll i tillfällig tabell
- Välj från temporär tabell till PL/SQL-array
- Infoga i faktisk tabell med bulkinsert från PL/SQL-array
Det är så mycket overhead och bortkastad verksamhet här. Allt du behöver göra är att ta informationen du infogar i v2d_temp
och fyll i vertical_design
direkt , helst med en INSERT INTO ... SELECT * FROM-sats. Du kommer att kräva en del förbearbetning för att konvertera en JSON-array till en fråga, men det är lätt att uppnå i antingen Java eller PL/SQL.
Det verkar säkert för mig att globala temporära tabeller inte är rätt lösning för ditt scenario.
"vår chef eller andra personer envisas med att göra något på sin väg, så du kan inte ändra på det"
Det du har är ett chefsproblem inte ett programmeringsproblem . Följaktligen är det off-topic när det gäller StackOverflow. Men här är några förslag ändå.
Det viktigaste att komma ihåg är att vi inte pratar om en kompromiss om någon suboptimal arkitektur:det som din chef föreslår kommer helt klart inte att fungera i en miljö med flera användare. så dina alternativ är:
- Ignorera
ORA-14452
fel, fortsätt in i produktionen och använd sedan "men du sa till mig att"-försvaret när allt går fruktansvärt fel. Detta är den svagaste pjäsen. - Skräp i hemlighet de globala tabellerna och implementera något som fungerar i ett scenario med flera användare. Detta är högrisk eftersom du inte har något försvar om du misslyckas med implementeringen.
- Prata med din chef. Berätta för dem att du stöter på
ORA-14452
fel, säg att du har gjort en viss undersökning och det verkar vara ett grundläggande problem med att använda globala temporära tabeller på det här sättet, men uppenbarligen har du förbisett något. Fråga dem sedan hur de kom runt det här problemet när de har implementerat det tidigare. Detta kan gå på flera sätt, kanske har de en lösning, kanske kommer de att inse att det här är fel sätt att använda globala temporära tabeller, kanske säger de åt dig att gå vilse. Oavsett vilket är detta det bästa tillvägagångssättet:du har tagit upp dina frågor till lämplig nivå.
Lycka till.