Oracle
 sql >> Base de données >  >> RDS >> Oracle

Forcer Oracle à supprimer la table des températures globales

Les tables temporaires globales Oracle ne sont pas des objets transitoires. Ce sont de véritables tables de tas. Nous les créons une fois et n'importe quelle session peut les utiliser pour stocker des données qui ne sont visibles que pour cette session .

L'aspect temporaire est que les données ne sont pas persistantes au-delà d'une transaction ou d'une session. Le détail clé de l'implémentation est que les données sont écrites dans un tablespace temporaire et non permanent. Cependant, les données sont toujours écrites sur le disque et lues à partir de celui-ci, il y a donc une surcharge notable liée à l'utilisation de tables temporaires globales.

Le fait est que nous ne sommes pas censés supprimer et recréer des tables temporaires. Si vous essayez de transférer la logique de style SQL Server dans Oracle, vous devriez envisager d'utiliser des collections PL/SQL pour conserver les données temporaires en mémoire. En savoir plus.

La cause spécifique de ORA-14452 est que nous ne pouvons pas supprimer une table temporaire globale qui a une persistance de portée de session si elle a contenu des données pendant la session. Même si la table est actuellement vide...

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>

La solution consiste à mettre fin à la session et à se reconnecter, ou (un peu bizarrement) à tronquer le tableau puis à le supprimer.

SQL> truncate table gtt23;

Table truncated.

SQL> drop table gtt23;

Table dropped.

SQL> 

Si une autre session utilise la table temporaire globale - et c'est possible (d'où le global nomenclature), vous ne pourrez pas supprimer la table tant que toutes les sessions ne seront pas déconnectées.

La vraie solution est donc d'apprendre à utiliser correctement les tables temporaires globales :créez des tables temporaires globales spécifiques pour correspondre à chaque rapport. Ou, comme je l'ai dit, utilisez plutôt des collections PL/SQL. Ou, même, apprenez simplement à écrire du SQL bien réglé. Souvent, nous utilisons des tables temporaires comme solution de contournement à une requête mal écrite qui pourrait être enregistrée avec un meilleur chemin d'accès.

Après avoir examiné votre code complet, le flux semble encore plus bizarre :

  1. Supprimer et recréer une table temporaire globale
  2. Remplir la table temporaire
  3. Sélectionner à partir d'une table temporaire dans un tableau PL/SQL
  4. Insérer dans la table réelle à l'aide d'une insertion en masse à partir d'un tableau PL/SQL

Il y a tellement de frais généraux et d'activités gaspillées ici. Tout ce que vous avez à faire est de prendre les données que vous insérez dans v2d_temp et remplissez directement vertical_design , idéalement avec une instruction INSERT INTO ... SELECT * FROM. Vous aurez besoin d'un prétraitement pour convertir un tableau JSON en une requête, mais cela est facile à réaliser en Java ou en PL/SQL.

Il me semble certain que les tables temporaires globales ne sont pas la bonne solution pour votre scénario.

"notre patron ou d'autres personnes persistent à faire quelque chose à leur manière, vous ne pouvez donc pas changer cela"

Ce que vous avez est un problème de boss pas un problème de programmation . Par conséquent, il est hors sujet en ce qui concerne StackOverflow. Mais voici quand même quelques suggestions.

L'essentiel à retenir est que nous ne parlons pas d'un compromis sur une architecture sous-optimale :ce que votre patron propose clairement ne fonctionnera pas dans un environnement multi-utilisateurs. donc, vos options sont :

  1. Ignorer le ORA-14452 erreur, passez à la production, puis utilisez la défense "mais vous m'avez dit de" quand tout va horriblement mal. C'est le jeu le plus faible.
  2. Détruisez secrètement les tables globales et implémentez quelque chose qui fonctionnera dans un scénario multi-utilisateurs. Il s'agit d'un risque élevé, car vous n'avez aucune défense si vous bâclez la mise en œuvre.
  3. Parlez à votre patron. Dites-leur que vous rencontrez le ORA-14452 erreur, disons que vous avez fait des recherches et qu'il semble un problème fondamental avec l'utilisation de tables temporaires globales de cette manière, mais vous avez évidemment oublié quelque chose. Ensuite, demandez-leur comment ils ont contourné ce problème lorsqu'ils l'ont déjà mis en œuvre. Cela peut aller de plusieurs façons, peut-être qu'ils ont une solution de contournement, peut-être qu'ils se rendront compte que ce n'est pas la bonne façon d'utiliser les tables temporaires globales, peut-être qu'ils vous diront de vous perdre. Dans tous les cas, il s'agit de la meilleure approche :vous avez fait part de vos préoccupations au niveau approprié.

Bonne chance.