Anuncios en tutorial de programación PLSQL

jueves, 5 de agosto de 2021

Cómo obtener información sobre los objetos almacenados en las bases de datos Oracle

Ya hemos hablado en un artículo anterior sobre el diccionario de datos de las bases de datos Oracle, la vista USER_OBJECTS de dicho diccionario contiene un registro por cada objeto de la base de datos del que somos propietarios (o mejor dicho, del que es propietario el esquema con el que estamos conectados a dicha base de datos.

USER_OBJECTS
USER_OBJECTS

Las columnas que se utilizan de forma más común dentro de esta vista son:

  • OBJECT_NAME: nombre del objeto.
  • OBJECT_TYPE: tipo de objeto (toma valores como PACKAGE (paquete PLSQL), PROCEDURE (procedimiento), FUNCTION (función) o TRIGGER.
  • STATUS: muestra el estado del objeto que puede ser VALID (válido) o INVALID (inválido).
  • LAST_DDL_TIME: indica la última vez que el objeto fue cambiado.

Consultas PLSQL utilizando la vista USER_OBJECTS

Como siempre lo mejor es utilizar algunos ejemplos para comprender mejor como se puede utilizar esta vista. La siguiente consulta SELECT muestra los nombres de todas las tablas de nuestro esquema:

SELECT object_name FROM user_objects WHERE object_type = 'TABLE' ORDER BY object_name;

Esta otra consulta muestra todos los objetos cuyo estado es inválido:

SELECT object_type, object_name FROM user_objects WHERE status = 'INVALID' ORDER BY object_type, object_name;

El estado de un programa PL/SQL (ya sea un paquete, un procedimiento o una función), toma el valor de INVALID cuando se cambia algún objeto de la base de datos del que depende. Cuando esto ocurre, dicho programa necesita ser recompilado, algo que la base de datos Oracle suele hacer automáticamente la siguiente vez que alguien intenta utilizar dicho programa.

La siguiente consulta muestra todos los objetos que han sido cambiados en el día actual:

SELECT object_type , object_name , last_ddl_time FROM user_objects WHERE last_ddl_time >= TRUNC (SYSDATE) ORDER BY object_type, object_name;

Como buscar en el código fuente PLSQL

El código fuente de todos los programas PL/SQL que hayamos compilado dentro de la base de datos Oracle está accesible en la vista USER_SOURCE cuyas columnas más significativas son:

  • NAME: nombre del objeto.
  • TYPE: tipo de objeto, que podría ser desde cualquier tipo de programa PLSQL hasta código Java o el código de un trigger.
  • LINE: número de líneas del código fuente.
  • TEXT: texto del código fuente.

USER_SOURCE
USER_SOURCE

Utilizando la tabla USER_SOURCE se pueden escribir consultas SELECT para:

  • Encontrar todas las ocurrencias de un determinado texto dentro del código.
  • Verificar que el código sigue los estándares de desarrollo fijados.
  • Determinar todos los programas PL/SQL que llaman a un paquete o subprograma concreto.

Por ejemplo, supongamos que en algún momento necesitamos cambiar la lista de parámetros y el código de una función PLSQL denominada CALCULAR_MEDIA en el paquete PK_ ESTADISTICAS. Está claro que después de realizados los cambios deberemos encontrar desde que otros programas, fuera del paquete PK_MATEMATICAS, se llama a esta función. Para hacerlo podemos utilizar la siguiente consulta SELECT:

SELECT name , line , text FROM user_source WHERE UPPER (text) LIKE '%PK_ ESTADISTICAS%.%CALCULAR_MEDIA%' ORDER BY name, line;

Está claro que esta consulta también encontrará comentarios que puedan contener la cadena 'PK_ESTADISTICAS.CALCULAR_MEDIA' y podrían no detectarse algunas llamadas a la función en las que PK_ ESTADISTICAS apareciera en una línea y CALCULAR_MEDIA en otra.

De cualquier forma, si asumimos que los estándares de codificación no nos permiten formatear el código de manera que nombre de paquete y nombre de programa vayan en líneas diferentes, la consulta anterior funcionaría correctamente y nos serviría para identificar todas los lugares dentro del código que necesitaríamos revisar.

Configuración de la compilación de los objetos PL/SQL

Para conocer la configuración de la forma de compilación de los objetos PLSQL almacenados deberemos utilizar la vista del diccionario de datos de la base de datos Oracle denominada USER_PLSQL_OBJECT_SETTINGS.

USER_PLSQL_OBJECT_SETTINGS
USER_PLSQL_OBJECT_SETTINGS

Dentro de esta vista encontramos los siguientes campos clave:

  • NAME: nombre del objeto.
  • TYPE: tipo de objeto.
  • PLSQL_OPTIMIZE_LEVEL: nivel de optimización que se utilizó al compilar el objeto referenciado.
  • PLSQL_CODE_TYPE: modo de compilación.
  • PLSQL_DEBUG: indica si el objeto fue compilado en modo depuración (debugging).
  • PLSQL_WARNINGS: tipo de avisos del compilador que se utilizaron en el momento de la compilación.

A continuación os dejo algunos ejemplos de consultas que utilizan la vista USER_PLSQL_OBJECT_SETTINGS.

La primera de ellas identifica los programas PLSQL que no han empleado de manera eficiente la funcionalidad de optimización del tiempo de compilación existente en las bases de datos Oracle.

SELECT name FROM user_plsql_object_settings WHERE plsql_optimize_level < 2;

Un nivel de optimización cero significa que realmente no existió optimización alguna. Si el nivel de optimización es uno, la optimización del tiempo de compilación será mínima. Ninguno de estos valores debería ser aceptable en un entorno de producción.

La siguiente consulta permite identificar aquellos programas PL/SQL que tienen deshabilitados los avisos por tiempo de compilación (avisos que pueden ser indicativos de la calidad de nuestro código):

SELECT name, plsql_warnings FROM user_plsql_object_settings WHERE plsql_warnings LIKE '%DISABLE%';

Para terminar solo indicaros que me he dejado en el tintero algunas vistas que también almacenan información útil sobre los objetos de la base de datos Oracle, como pueden ser USER_PROCEDURES, USER_TRIGGERS o USER_DEPENDENCIES, pero estás serán objeto de otro u otros artículos.

1 comentarios:

Oscar Ramirez dijo...

Buen Post y muchas gracias por subirlo. Pero las consultas que haces muestran Objetos del Current_User. Para buscar un objeto (Any) cual sea este seria el Query:
-- Buscar un OBJETO de la base de datos
Select *
from dba_objectS
where object_name =UPPER('MYTESTTABLE');