Probablemente ya has leído sobre estas funcionalidades, son bastante útiles pero limitadas a los usuarios de Oracle 23ai, o lo estaban: desde hace pocos días están disponibles para quienes usen Oracle 19c y actualicen al Release Update 19.28.
Sin más demoras, veamos de qué se trata, cómo usarlas y, sobre todo, en qué situaciones nos pueden ayudar.
IF [NOT] EXISTS
Los comandos CREATE, ALTER y DROP pueden fallar, dependiendo de la existencia o no del objeto referenciado.
Por ejemplo, para el caso de CREATE, si el objeto ya existe nos encontraremos con el siguiente error:
SQL> CREATE TABLE test_table (
id NUMBER
);
CREATE TABLE test_table (
*
ERROR at line 1:
ORA-00955: name is already used by an existing object
Ahora es posible agregarle IF NOT EXISTS, para así eliminar estos errores cuando el objeto ya existe.
SQL> CREATE TABLE IF NOT EXISTS test_table (
id NUMBER
);
Table created.
Por otro lado, para el caso de DROP, si el objeto ya no existe nos encontraremos con el siguiente error
SQL> DROP TABLE test_table;
*
ERROR at line 1:
ORA-00942: table or view does not exist
Estos errores desaparecen si agregamos IF EXISTS.
SQL> DROP TABLE IF EXISTS test_table;
Table dropped.
Para conocer más a fondo de esta funcionalidad, consideraciones, limitaciones y abundantes ejemplos, dale una leída a este artículo escrito por el mítico Tim Hall.
SQL Diagnostic Report
Cuando queremos analizar el desempeño de un query necesitamos mucha información: la estructura de las tablas, sus índices, los planes de ejecución y su historial, los valores de las bind variables, etc.
Oracle nos proporciona herramientas como SQLTXPLAIN o SQL Tuning Health-Check Script (SQLHC) para recopilar toda esta información, y si bien podemos seguirlas usando, ¿no sería más simple si ya viniera de fábrica?
Pues ya lo está: bienvenida la función REPORT_SQL del paquete DBMS_SQLDIAG.
Solo necesitamos conocer el SQL_ID y listo, Oracle generará un archivo HTML comprimido en el directorio que le indiquemos, con un nombre que respeta el siguiente patrón:
SQLR_{{SQL_ID}}_{{YYYYMMDDHH24MI}}.zip
DECLARE
report CLOB;
BEGIN
report := DBMS_SQLDIAG.report_sql(
sql_id => 'g4d8ysyx34vaz',
directory => 'DATA_PUMP_DIR',
level => 'ALL');
END;
/
$ ls -ltA /u01/app/oracle/19.0.0/db_2/rdbms/log/
total 56
-rw-r--r-- 1 oracle asmadmin 25472 Jul 29 12:15 SQLR_g4d8ysyx34vaz_202507291215.zip
-rw-r----- 1 oracle asmadmin 4098 Jul 28 22:01 qopatch_log.log
drwxr-x--- 3 oracle oinstall 291 Jul 28 22:01 opatch
-rw-r----- 1 oracle asmadmin 1137 Jul 28 03:16 db1928_1_ora_13505.trc
-rw-r----- 1 oracle asmadmin 851 Jul 28 03:16 db1928_1_ora_13484.trc
-rw-r----- 1 oracle asmadmin 1137 Jul 27 15:49 db1928_1_ora_16106.trc
-rw-r----- 1 oracle asmadmin 161 Jul 27 15:43 dp.log
-rw-r----- 1 oracle asmadmin 992 Jul 27 15:38 db1928_1_ora_4332.trc
Si te resulta complicado tener que acceder al directorio en el servidor de base de datos, puedes obtener los contenidos del archivo HTML sin tener que generar el archivo comprimido:
VAR report CLOB;
BEGIN
:report := DBMS_SQLDIAG.report_sql(
sql_id => 'g4d8ysyx34vaz',
level => 'BASIC');
END;
/
SET feedback off
SET trimspool on
SET trim on
SET pagesize 0
SET linesize 32767
SET long 1000000
SET longchunksize 1000000
SPOOL diag_g4d8ysyx34vaz.html
PRINT :report
SPOOL OFF
SELECT dep.department_name,
COUNT(*) emp_count,
MAX(salary) max_salary
FROM employees emp,
departments dep
WHERE emp.department_id = :deptno
AND emp.department_id = dep.department_id
GROUP BY department_name;
Para más detalles de esta funcionalidad, échale un ojo a este artículo escrito por Ulrike Schwinn.
Ahora sí, aplica el RU 19.28 y empieza a disfrutar de las bondades de estas nuevas funcionalidades!