INSTR para buscar caracteres

El objetivo principal de este post, es saber los distintos file systems en que están viviendo los data files de una base de datos.

Para hacer esto, se deben hacer búsquedas de caracteres para poder manipular y traer sólo la primer parte de un file system.

Aquí muestro cómo se puede hacer esto fácilmente, dado que he visto que muchas personas tienen algo de dificultad para realizar este tipo segmentación de información.

Primero quiero saber cuáles son los distintos data files que se tienen en la base de datos, esto se logra fácilmente consultando la vista DBA_DATA_FILES:

SQL> select file_name
 2 from dba_data_files
 3 where rownum < 5;

FILE_NAME
----------------------------------------------
/oracle/ooo/datafile/users01.dbf
/oracle/ooo/datafile/undotbs01.dbf
/oracle/ooo/datafile/sysaux01.dbf
/oracle/ooo/datafile/system01.dbf

En este momento, ya sabemos que /oracle es el único file system que está albergando los data files; sin embargo, estamos buscando una consulta que nos dé la información de manera elegante y funcional.

Para esto, usaremos la función INSTR del SQL de Oracle. Esta tiene el formato siguiente:

instr (texto_base, texto_a_buscar [, inicio, ocurrencia])

Lo que está entre corchetes ([]), es opcional, si no se ponen esos números, entonces la función devuelve cero (0) si no se encontró el texto_a_buscar en texto_base o la posición que el texto_a_buscar ocupa en la primer ocurrencia en el texto_base.

Si se incluye el caracter de inicio, entonces la función comenzará a buscar a partir de este en el texto_base.

Si se pone un número de ocurrencia, entonces, buscará la posición de esta correspondiente en el texto_base.

Ejemplos:

Si tenemos:       12345678901234567890123456789  <- Posición
    texto_base = 'MetallicA is louder than hell'
texto_a_buscar = 'l'
entonces:
 0 <- instr (texto_base, 'p')
 5 <- instr (texto_base, texto_a_buscar)
 6 <- instr (texto_base, texto_a_buscar, 6)
14 <- instr (texto_base, texto_a_buscar, 6, 2)
14 <- instr (texto_base, texto_a_buscar, 1, 3)

Entonces, con base en estos ejemplos del uso de la función INSTR, podemos pasar a ver los distintos efectos que tiene en el listado de data files que se mostró previamente. Primero, vamos a ver en dónde está la primer ocurrencia a partir del primer caracter de la diagonal (/):

SQL> select instr (file_name, '/', 1, 1)
 2 from dba_data_files
 3 where rownum < 5;

INSTR(FILE_NAME,'/',1,1)
------------------------
 1
 1
 1
 1

Ahora hay que ver qué posición en el texto ocupa la segunda ocurrencia de la diagonal (/) a partir del primer caracter:

SQL> select instr (file_name, '/', 1, 2)
 2 from dba_data_files
 3 where rownum < 5;

INSTR(FILE_NAME,'/',1,2)
------------------------
 8
 8
 8
 8

Ahora, a partir la primer caracter, ¿en qué posición está la tercer ocurrencia?:

SQL> select instr (file_name, '/', 1, 3)
 2 from dba_data_files
 3 where rownum < 5;

INSTR(FILE_NAME,'/',1,3)
------------------------
 12
 12
 12
 12

¿Y la cuarta ocurrencia?:

SQL> select instr (file_name, '/', 1, 4)
 2 from dba_data_files
 3 where rownum < 5;

INSTR(FILE_NAME,'/',1,4)
------------------------
 21
 21
 21
 21

Ya sabiendo estas distintas posiciones de las diagonales que marcan el límite de los distintos directorios, nos podemos apoyar en la función SUBSTR para sacar el segmento de texto que hay entre el caracter 1 y la ubicación de la segunda ocurrencia de la diagonal:

SQL> select substr (file_name, 1, instr (file_name, '/', 1, 2) - 1)
 2 from dba_data_files
 3 where rownum < 5;

SUBSTR(FILE_NAME,1,INSTR(FILE_NAME,'/',1,2)-1)
----------------------------------------------
/oracle
/oracle
/oracle
/oracle

Con lo que resta sólo sacar los diferentes valores obtenidos con la opción DISTINCT del SELECT:

SQL> select distinct substr (file_name, 1, instr (file_name, '/', 1, 2) - 1)
 2 from dba_data_files;

SUBSTR(FILE_NAME,1,INSTR(FILE_NAME,'/',1,2)-1)
----------------------------------------------
/oracle

Tras lo cual, sabemos que /oracle es el único file system donde están ubicados los data files.

Pero, ¿qué pasa si los data files están en un disk group de Oracle ASM?

Con una pequeña modificación y el uso de la función DECODE para saber si el primer caracter es un mas (+) para un disk group o una diagonal (/) para un file system, podemos tener una consulta totalmente genérica:

SQL> select distinct
 2          decode (substr (file_name, 1, 1), '+', substr (file_name, 1, instr (file_name, '/', 1, 1) -1),
 3                                                  substr (file_name, 1, instr (file_name, '/', 1, 2) - 1)) holder
 4 from dba_data_files;

HOLDER
----------------------------------------------------------------------------------------------------------------------------------------------------------------
+DATA

1 row selected.

Y ahora sabemos que +DATA es el único disk group que está guardando data files.

Y también tenemos una bastante útil consulta que nos mostrará los diferentes file systems donde están guardados los data files de cualquier base de datos.

Si la información de este post te ha sido de utilidad o quieres que agregue algo más, deja por favor un comentario, contestaré a la brevedad.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

A %d blogueros les gusta esto: