lunes, 8 de mayo de 2023

Oracle 23c - Nueva funcionalidad DOMAIN

Oracle 23c introduce un nuevo concepto llamado DOMAIN que permite definir en un único lugar las propiedades y restricciones relacionados con un dato en particular (como ser un numero de telefono o una dirección de mail) y posteriormente utilizar el mismo en todas aquellas columnas que formen parte de ese "dominio".

En este artículo nos vamos a concentrar en la forma más básica de esta nueva funcionalidad, que son los dominios simples.


Creando un Dominio Simple (de una columna)

Existen diversos tipos de dominios, los cuales incluyen muchas funciones avanzadas. Vamos a comenzar con un ejemplo para crear un dominio sencillo, que nos permita definir, por ejemplo, las características de un número de CUIT (Clave Unica de Identificación Tributaria) utilizado en Argentina.

Vamos a crear el mismo usando el tipo de datos VARCHAR2, con un tamaño máximo de veinte caracteres, y usaremos una expresión regular para validar que el mismo cumpla con el formato válido, el cual consta once dígitos, los cuales se visualizan como sección de dos dígitos seguidos de ocho dígitos adicionales y un dígito de control, separados entre sí por dos guiones:

CREATE DOMAIN d_NRO_CUIT AS VARCHAR2(20)
CONSTRAINT chk_nro_cuit CHECK (REGEXP_LIKE (d_NRO_CUIT, '^[0-9]{11}$'))
DISPLAY(SUBSTR(d_NRO_CUIT,1,2)||'-'||SUBSTR(d_NRO_CUIT,3,8)||'-'||SUBSTR(d_NRO_CUIT,11,1));

Nota: Para crear un dominio se requiere el privilegio CREATE DOMAIN, el cual forma parte del nuevo rol DB_DEVELOPER_ROLE como explicamos en el artículo "Oracle 23c - Nuevo Rol DB_DEVELOPER_ROLE".


Una vez que creamos el dominio, podemos utilizarlo para definir columnas en tablas de nuestra base de datos, las cuales heredarán todas sus características (por el momento, sólo veremos el tipo de datos, tamaño, una función de check y un formato de visualización, pero hay algunas más).

CREATE TABLE tCliente ( ID_Cliente NUMBER(10) CONSTRAINT PK_Cliente PRIMARY KEY, Nombre_Cliente VARCHAR2(100) NOT NULL, CUIT_Cliente DOMAIN d_NRO_CUIT NOT NULL);


Paso siguiente, vamos a probar de insertar dos registros distintos en nuestra tabla usando el siguiente script:

INSERT INTO tCliente VALUES (1, 'Supermercado Genial', '34123456789'); INSERT INTO tCliente VALUES (2, 'Distribuidora MaxiPrecios', '3412345678A');

Obteniendo el siguiente resultado:


Podemos ver que la segunda fila no fue insertada ya que el valor provisto para el campo CUIT_Cliente no satisface las reglas expresadas en la restricción definida para el dominio, que debe ser de 11 dígitos.

Vamos a consultar los datos insertados, y vamos a usar la función DOMAIN_DISPLAY aplicada a la columna CUIT_Cliente para ver el contenido de la columna pero con el formato especificado en el dominio:

SELECT ID_Cliente, Nombre_Cliente, CUIT_Cliente, DOMAIN_DISPLAY(CUIT_Cliente) FROM tCliente;

Lo cual nos muestra lo siguiente:


Así como podemos definir un tipo de datos, tamaño y restricción de tipo CHECK, también podemos definir otras condiciones al crear un DOMAIN, como ser:

  • DISPLAY: Permite definir un formato en que se mostrará el dato. Por ejemplo, convertir la primer letra de cada palabra a mayúsculas y el resto en minúsculas usando la función INITCAP.
  • ORDER: Permite definir un formato para ordenar los datos. Por ejemplo, ordenar convirtiendo un texto todo a mayúsculas o minúsculas.
  • COLLATE: Si estamos usando tipode datos de texto extendido, podemos usar esta opción para indicar que la columna sea de tipo CASE INSENSITIVE en las búsquedas.

Funciones de Dominio

Ya vimos en el ejemplo anterior el uso de DOMAIN_DISPLAY, la cual nos permite ver la información de una columna con el formato especificado en el dominio. Existen otras funciones que nos devuelven información respecto a las columnas y los dominios al que están asociadas. En el ejemplo siguiente podemos ver algunas de ellas (el resto se pueden ver en la documentación).


La función DOMAIN_NAME nos muestra el dominio asociado a una columna:

SELECT DOMAIN_NAME(CUIT_Cliente) AS Dominio FROM tCliente;

DOMINIO ---------------------------------------- DEMO.D_NRO_CUIT


La función DOMAIN_CHECK nos permiten validar si un dato cumple con las condiciones especificadas en la restricción de tipo CHECK de un dominio, como vemos a continuación:

SELECT DOMAIN_CHECK('d_NRO_CUIT','00123456789') AS Sin_CAST, DOMAIN_CHECK('d_NRO_CUIT',CAST ('00123456789' AS VARCHAR2(100))) AS Con_CAST_OK, DOMAIN_CHECK('d_NRO_CUIT',CAST ('AA123456789' AS VARCHAR2(100))) AS Con_CAST_ERROR;

Lo cual nos muestra el siguiente resultado:


Nota: Si queremos validar un valor que cumple con la condición en forma directa, igualmente nos devuelve como resultado 0. Es necesario hacer un CAST al tipo de datos esperado por el dominio para que funciones correctamente, como se muestra en el ejemplo. Esto seguramente será corregido en el corto plazo para que el CAST no sea necesario.


Ver relación de columnas con Dominios usando DESC

Al describir una tabla con el comando DESC, ahora no sólo muestra el tipo de datos de las columnas sino que también muestra si la misma está asociada a un dominio, como vemos a continuación:

SQL> DESC tCliente
Name Null? Type ----------------------------------------- -------- ---------------------------- ID_CLIENTE NOT NULL NUMBER(10) NOMBRE_CLIENTE NOT NULL VARCHAR2(100) CUIT_CLIENTE NOT NULL VARCHAR2(20) DEMO.D_NRO_CUIT


Vistas de Diccionario de Datos

Los Dominios son un nuevo tipo de objetos en las bases de datos, y podemos verlos en las vistas del diccionario de datos como ser USER_OBJECTS:

SELECT object_name, object_type
FROM user_objects;

OBJECT_NAME OBJECT_TYPE -------------------- -------------------- TCLIENTE TABLE D_NRO_CUIT DOMAIN PK_CLIENTE INDEX


La vista USER_TAB_COLUMNS incorpora dos nuevas columnas para ver la información de dominios asociada a una columna, como podemos ver a continuación:

SELECT column_id, column_name, domain_owner, domain_name FROM user_tab_columns;

COLUMN_ID COLUMN_NAME DOMAIN_OWNER DOMAIN_NAME ---------- -------------------- -------------------- -------------------- 1 ID_CLIENTE 2 NOMBRE_CLIENTE 3 CUIT_CLIENTE DEMO D_NRO_CUIT


Y se incorporan tres nuevas vistas que muestran información específica de los dominios:

SELECT * FROM user_domains; SELECT * FROM user_domain_cols; SELECT * FROM user_domain_constraints;


Conclusión

Si bien analizamos sólo el tipo de DOMAIN mas sencillo, podemos ver que es una funcionalidad muy completa que puede facilitar el diseño de una base de datos al poder definir reglas y atributos comunes a muchas columnas bajo un único dominio, y luego crear las columnas especificando el dominio para que las mismas hereden automáticamente estas validaciones y atributos.


Si desean conocer más sobre Oracle 23c, es recomendable que vean estos artículos en este blog como punto de partida:

Adicionalmente, pueden consultar todos los artículos relacionados a Oracle Database 23c agrupados en en el tag Database 23c.



No hay comentarios.:

Publicar un comentario