sql >> Base de Datos >  >> RDS >> Oracle

Forzar Oracle Drop Global Temp Table

Las tablas temporales globales de Oracle no son objetos transitorios. Son tablas de montón adecuadas. Los creamos una vez y cualquier sesión puede usarlos para almacenar datos que solo son visibles para esa sesión .

El aspecto temporal es que los datos no son persistentes más allá de una transacción o una sesión. El detalle clave de la implementación es que los datos se escriben en un tablespace temporal, no en uno permanente. Sin embargo, los datos todavía se escriben y se leen en el disco, por lo que hay una sobrecarga notable en el uso de tablas temporales globales.

El punto es que no debemos descartar y recrear tablas temporales. Si está intentando portar la lógica del estilo de SQL Server a Oracle, entonces debería considerar usar colecciones PL/SQL para mantener datos temporales en la memoria. Saber más.

La causa específica de ORA-14452 es que no podemos descartar una tabla temporal global que tenga persistencia en el ámbito de la sesión si ha contenido datos durante la sesión. Incluso si la mesa está actualmente vacía...

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 solución es finalizar la sesión y volver a conectarse, o (algo extraño) truncar la tabla y luego soltarla.

SQL> truncate table gtt23;

Table truncated.

SQL> drop table gtt23;

Table dropped.

SQL> 

Si alguna otra sesión está utilizando la tabla temporal global, y eso es posible (de ahí el global nomenclatura), entonces no podrá soltar la mesa hasta que todas las sesiones se desconecten.

Entonces, la solución real es aprender a usar las tablas temporales globales correctamente:crear tablas temporales globales específicas para que coincidan con cada informe. O, como digo, use colecciones PL/SQL en su lugar. O, incluso, simplemente aprenda a escribir SQL bien ajustado. A menudo usamos tablas temporales como solución a una consulta mal escrita que podría guardarse con una mejor ruta de acceso.

Habiendo mirado su código completo, el flujo parece aún más extraño:

  1. Soltar y volver a crear una tabla temporal global
  2. Rellenar tabla temporal
  3. Seleccione de la tabla temporal a la matriz PL/SQL
  4. Insertar en la tabla real usando la inserción masiva desde la matriz PL/SQL

Hay tantos gastos generales y actividad desperdiciada aquí. Todo lo que necesita hacer es tomar los datos que inserta en v2d_temp y llene directamente vertical_design , idealmente con una declaración INSERT INTO ... SELECT * FROM. Necesitará un procesamiento previo para convertir una matriz JSON en una consulta, pero eso es fácil de lograr en Java o PL/SQL.

Me parece seguro que las tablas temporales globales no son la solución adecuada para su escenario.

"nuestro jefe u otras personas persisten en hacer algo a su manera, por lo que no puedes cambiar eso"

Lo que tienes es un problema de jefe no es un problema de programación . En consecuencia, está fuera de tema en lo que respecta a StackOverflow. Pero aquí hay algunas sugerencias de todos modos.

La clave para recordar es que no estamos hablando de un compromiso sobre una arquitectura subóptima:lo que su jefe propone claramente no funcionará en un entorno multiusuario. Entonces, tus opciones son:

  1. Ignorar el ORA-14452 error, continúe con la producción y luego use la defensa "pero usted me dijo que lo hiciera" cuando todo salga terriblemente mal. Esta es la jugada más débil.
  2. Deshágase de las tablas globales de forma encubierta e implemente algo que funcione en un escenario multiusuario. Esto es de alto riesgo porque no tiene defensa si falla en la implementación.
  3. Habla con tu jefe. Diles que te encuentras con el ORA-14452 error, digamos que ha investigado un poco y parece un problema fundamental con el uso de tablas temporales globales de esta manera, pero obviamente ha pasado por alto algo. Luego, pregúnteles cómo solucionaron este problema cuando lo implementaron antes. Esto puede ir de varias maneras, tal vez tengan una solución alternativa, tal vez se den cuenta de que esta es la forma incorrecta de usar tablas temporales globales, tal vez le digan que se pierda. De cualquier manera, este es el mejor enfoque:ha planteado sus inquietudes al nivel apropiado.

Buena suerte.