lunes, 29 de mayo de 2023

Oracle Linux 9.2 y Linux 8.8 ya están disponibles

El miércoles pasado Oracle liberó las versiones 8.8 y 9.2 de Oracle Linux,para las plataformas Intel y AMD de 64 bits (x86_64) y Arm de 64 bits (aarch64). 

Estas versiones son 100 % compatibles con las versiones correspondientes de Red Hat Enterprise Linux 9 Update 2 y 8 Update 8. Ambos lanzamientos se envían con los paquetes Unbreakable Enterprise Kernel Release 7 Update 1 (UEK R7U1) y Red Hat Compatible Kernel (RHCK) más nuevos.


Oracle Linux 9 Update 2 incluye las siguientes opciones de kernel:

  • UEK R7U1, kernel-uek-5.15.0-101.103.2.1 para plataformas x86_64 y aarch64
  • Kernel compatible con Red Hat (RHCK), kernel-5.14.0-284.11.1 para la plataforma x86_64


Oracle Linux 8 Update 8 incluye las siguientes opciones de kernel:

  • UEK R7U1, kernel-uek-5.15.0-101.103.2.1 para plataformas x86_64 y aarch64
  • Kernel compatible con Red Hat (RHCK), kernel-4.18.0-477.10.1 para la plataforma x86_64


Principales Mejoras

Sistema operativo y gestión de software

Oracle Linux ahora admite actualizaciones fuera de línea. Las actualizaciones offline pueden ayudar a proteger un sistema al realizar instalaciones de paquetes después de un reinicio y antes de que se carguen las bibliotecas que podrían verse afectadas por las actualizaciones de paquetes. Con esta mejora, los servicios en ejecución no se verán afectados por las actualizaciones del sistema operativo.


Gestión mejorada en contenedores

Oracle Linux ahora incluye un paquete de herramientas de contenedores actualizado que ofrece una integración mejorada entre Oracle Linux mejoras en los tiempos de ejecución de contenedores locales; este paquete incluye versiones mejoradas para las herramientas Podman, Buildah, Skopeo, crun y runc.

Oracle Linux 9 Update 2 y Oracle Linux 8 Update 8 pueden ejecutar cargas de trabajo en contenedores en systemd para implementaciones más confiables. Esta integración permite que systemd administre las dependencias de los servicios, supervise el ciclo de vida y el estado del servicio, reinicie los servicios en caso de falla y administre las actualizaciones/retrocesos automáticos para sus contenedores.


Mejoras en Observabilidad

Oracle Linux 9 Update 2 incluye Grafana v.9, una versión que mejora la facilidad de uso de Grafana, el descubrimiento de datos a través de nuevos modelos de visualización y la funcionalidad de alertas de Grafana. Grafana, parte de Oracle Linux, hace que la observación y la visualización de datos sean más fáciles y accesibles.


Gestión de Seguridad y Compliance mas Sencilla

Cockpit, disponible para Oracle Linux 8 y Oracle Linux 9, es una interfaz gráfica de escritorio web para servidores individuales y le permite iniciar fácilmente contenedores, administrar almacenamiento, administrar máquinas virtuales KVM, configurar redes e inspeccionar registros. Esta consola web presenta la opción de administrar el desbloqueo de discos cifrados para sistemas de archivos raíz mediante NBDE (cifrado de disco vinculado a la red). Proporciona a los administradores un método facilitado para aprovechar las políticas criptográficas de todo el sistema y mantener los sistemas asociados en cumplimiento con los estándares y políticas definidos.


Gestión de red mejorada

La versión 1.42.2 de NetworkManager, disponible con Oracle Linux 9 Update 2, incluye mejoras importantes para configurar y administrar correctamente la configuración de red en los sistemas de servidor:

  • Los enlaces Ethernet (alta disponibilidad para redes) se pueden configurar para el equilibrio de carga de origen
  • Etiquetado 802.1ad en conexiones de redes de área local virtuales (VLAN)
  • Para dispositivos perimetrales modernos, la aplicación nmtui se puede usar con perfiles de conexión Wi-Fi WPA-Enterprise, Ethernet con autenticación 802.1X y MACsec
  • NetworkManager se actualiza para rechazar las concesiones de DHCPv6 si todas las direcciones fallan en la detección de direcciones duplicadas de IPv6.

Sistema de archivos y almacenamiento

Oracle Linux 9 Update 2 y Oracle Linux 8 Update 8, con UEK R7U1, continúan manteniendo y brindando soporte para el sistema de archivos btrfs, para acceder a uno de los sistemas de archivos de copia en escritura (COW) más modernos para Linux.


Documentación Oracle Linux 8.8

 Los siguientes links permiten acceder a la documentación de Oracle Linux 8 Update 8:


Documentación Oracle Linux 9.2

 Los siguientes links permiten acceder a la documentación de Oracle Linux 9 Update 2:

Descarga de Oracle Linux 8.8 y 9.2


jueves, 25 de mayo de 2023

Actualizando a Oracle APEX 23.1 en Oracle Cloud

La semana pasada mencionábamos en este artículo la disponibilidad de APEX 23.1 tanto para instalar on-premise como en Oracle Cloud Infrastructure, en donde se iría habilitando en las distintas regiones en los días siguientes. Ayer quedó habilitada en la region US East la posibilidad de actualizar APEX, por lo que mostraremos en este artículo como hacerlo.

Hay que tener en cuenta que las actualizaciones se aplican en forma automática a los 45 días si no se hace manualmente antes.


Controlando si el Upgrade está Disponible

Además de verlo en la consola de administración de APEX, podemos ejecutar la siguiente consulta para validar si hay alguna actualización disponible en nuestra base de datos autónoma:

select APEX_INSTANCE_ADMIN.get_parameter('UPGRADE_STATUS') as UPGRADE_STATUS from dual;

En nuestro caso, vemos que hay una actualización disponible la cual está agendada para ser realizada en forma automática:


Actualizando la instancia de APEX

Los pasos para actualizar la instancia de APEX son por demás de sencillos. Antes que nada, tenemos que ingresar a la consola de APEX a la sección de Servicios Administrativos, donde veremos en el sector derecho de la pantalla el siguiente mensaje:


Al presionar el botón "Upgrade Now" veremos la siguiente confirmación:


Tras confirmar que queremos actualizar la version de APEX presionando "Upgrade Now", la página se refresca mostrando en su cabecera que APEX esta siendo actualizado:


Así como en el sector derecho de la consola aparece también el indicador que APEX esta siendo actualizado:


Y si volvemos a ejecutar la consulta inicial desde Database Actions, veremos que la misma esta en ejecución:


Confirmando la Actualización

Tras unos pocos minutos, la actualización culmina y podemos ver que APEX se ha actualizado de diversas maneras.

Pie de Página

El pie de página de APEX incluye la versión:



Ventana de "Acerca de ..."

La ventana de "Acerca de..." en el menu de ayuda nos muestra todos los detalles de nuestro workspace



Sentencia SQL 

Mediante la siguiente sentencia SQL, podemos ver la versión disponible:

SELECT * FROM apex_release;

La cual, después de la actualización, nos muestra lo siguiente:


Controlando la Disponibilidad de Actualizaciones

Luego de actualizar APEX, si volvemos a consultar si hay actualizaciones disponibles usando la misma sentencia utilizada al principio del artículo:

select APEX_INSTANCE_ADMIN.get_parameter('UPGRADE_STATUS') as UPGRADE_STATUS from dual;


Veremos el siguiente estado:


 

martes, 23 de mayo de 2023

APEX 22.2 Patchset Bundle #6 ya está disponible!

Este conjunto de patchsets agrupado bajo el número de patch 34628174 fue liberado ayer y está disponible sólo desde la página de soporte de Oracle en este link.

Se puede consultar la lista de fixes incluidos en el patchset bundle en este link.

La versión base de Oracle APEX 22.2 puede ser descargada aquí.


lunes, 22 de mayo de 2023

Oracle 23c & JSON - Relational Duality Views - Parte #3


En este artículo final de la serie de JSON Relational Duality Views, vamos a analizar las ventajas y casos de uso que nos ofrece esta nueva funcionalidad de Oracle Database 23c.


Algunas Ventajas de JSON Relational Duality Views


Alta Concurrencia

JSON Relational Duality Views introducen control de concurrencia sin bloqueo previo (concurrencia optimista), basado en versiones que contempla la actualización de datos tanto mediante el UPDATE de un documento JSON como la ejecución de sentencias UPDATE en forma directa a las tablas relacionales involucradas.


Eliminación de Datos Duplicados

Las bases de datos de documentos tienen (en general) el problema de mantener sus documentos independientes. Al no tener un buen mecanismo para declarar relaciones entre documentos, que genera duplicación de datos e inconsistencias. Los datos duplicados conducen a mayores costos de mantenimiento, errores en la toma de decisiones y oportunidades comerciales perdidas.

JSON Relational Duality elimina la duplicación de datos ya que la información de un único documento JSON es almacenada mediante transacciones ACID (atomicidad, consistencia, aislamiento, durabilidad) en diversas tablas relacionales, eliminando la duplicación de datos pero manteniendo la consistencia automáticamente.


Datos Accesibles en Múltiples Documentos

Las bases de datos de documentos no son flexibles cuando debemos tener información compartida entre distintas jerarquías. Si deseamos tener información de los productos en los documentos de Compras y Ventas, es probable que tengamos que duplicar la misma en ambas jerarquías, o que debamos usar una tercer jerarquía que se relacione a ambas pero sacrificando la integridad y generando un modelo mixto (documentos relacionados) que suma mas problemas que lo que soluciona.

Las vistas duales JSON Relational permiten definir multiples múltiples vistas de JSON en grupos de tablas superpuestas. Este modelado de datos flexible hace que la creación de múltiples aplicaciones con los mismos datos sea fácil y eficiente, permitiendo por ejemplo que la tabla relacional de productos sea incluida tanto en la vista de Compras como la de Ventas, siendo actualizable en ambas pero almacenada en forma única y consistente.


Eliminar Roundtrips

Al desarrollar una aplicación es necesario mapear entre objetos de nivel de aplicación (como clases, utilizados por lenguajes de programación) y las tablas relacionales. Es normal tener que modificar datos de varias tablas para implementar un caso de uso empresarial, lo cual genera un problema llamado "desajuste de impedancia relacional de objetos". Es frecuente el uso de frameworks (Object Relational Mapping - ORM) que facilitan las tareas de mapeo, pero en general es a expensas de performance ya que no utilizan las funciones avanzadas que ofrecen las bases de datos. Dado que una operación en un objeto de nivel de aplicación puede dar lugar a múltiples accesos o actualizaciones de las tablas participantes, esto ralentiza el rendimiento de la aplicación.

JSON Relational Duality Views elimina la necesidad de asignar objetos a tablas relacionales a nivel de la aplicación, proporcionando vistas JSON totalmente actualizables sobre los datos almacenados en forma relacional. Las aplicaciones pueden leer un documento, realizar los cambios necesarios y volver a escribir el documento sin preocuparse por la estructura de datos subyacente, el mapeo, la consistencia o el ajuste del rendimiento, permitiendo recuperar o almacenar todos los datos necesarios para una aplicación en una sola operación de base de datos.


Lo Mejor de Ambos Mundos

En definitiva, con JSON Relational Duality Views podemos unir las ventajas de ambos mundos!



JSON Relational Duality Views permite:
  • Eliminar el uso de frameworks de ORM para mapear información de las aplicaciones al modelo de datos relacional que la almacena.
  • Acceder a la información relacional mediante APIs de documentos como ser Oracle REST Data Services u Oracle Database API for MongoDB.

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.

viernes, 19 de mayo de 2023

Oracle 23c & JSON - Relational Duality Views - Parte #2


En este segundo artículo sobre JSON Relational Duality Views vamos a analizar algunas características mas avanzadas de las mismas y vamos a analizar también las vistas del diccionario de datos que contienen información sobre esta nueva funcionalidad.


Control de Concurrencia Optimista

En el articulo anterior "Oracle 23c & JSON - Relational Duality Views - Parte #1" estuvimos actualizando documentos JSON mediante el uso de vistas duales, pero no contemplamos la posibilidad que los datos subyacentes hayan cambiado, algo que en la vida real ocurre frecuentemente.

Duality Views utiliza una nueva arquitectura de control de concurrencia optimista o sin bloqueo disponible en Oracle Database 23c que permite a los desarrolladores administrar sus datos de manera consistente en operaciones sin estado (como ser REST GET y PUT), ya que los bloqueos tienen estado y no se pueden retener en llamadas sin estado.

Este nuevo algoritmo posee las siguientes características:

  • Incorpora el concepto de etiqueta de entidad (ETAG) del protocolo HTTP a la base de datos, siendo una ETAG un hash o una firma para el contenido de una página web recuperada, pero esto aplicado a documentos.
  • Cuando se realiza un GET en Duality View, el documento JSON devuelto también contiene el ETAG del conjunto de filas utilizadas en la construcción del documento.
  • Cuando ese documento se modifica y luego se vuelve a poner en la base de datos, el ETAG proporcionado se compara con el ETAG actual de las filas. Si el ETAG difiere, el objeto debe haber sido modificado por otra sesión entre el momento en que se hizo el GET y el momento en que se envió el PUT, por lo que el PUT es rechazado. La aplicación puede volver a obtener la versión mas actualizada del documento (el cual contiene un nuevo ETAG) mediante un GET, aplicarle los cambios requeridos, y volver a intentar hacer un PUT.
  • Si el PUT tiene éxito, tenemos la garantía de que no se han producido cambios intermedios en el objeto y garantizamos la atomicidad y la coherencia a nivel de documento.

Este tipo de control de concurrencia sin bloqueo permite a los desarrolladores centrarse en su aplicación sin tener que implementar control de concurrencia dentro de la aplicación.


Control de Concurrencia Optimista en Funcionamiento

Vamos a ver como funciona el control de concurrencia en la práctica. Lo primero que vamos a hacer es consultar un documento en particular, usando los ejemplos del artículo "Oracle 23c & JSON - Relational Duality Views - Parte #1" donde comenzamos a explicar como funcionan las vistas duales.


Vamos a obtener el documento JSON asociado al comprobante #3, usando la siguiente sintaxis:

SELECT JSON_SERIALIZE(c.data PRETTY) FROM VDCOMPROBANTE c WHERE c.data.IDComprobante = 3;


Lo cual devuelve el siguiente documento:

JSON_SERIALIZE(C.DATAPRETTY) --------------------------------------------------------------------- { "_metadata" : { "etag" : "66C4365F9A178623F27913B947DF8C7C", "asof" : "00000000007844AF" }, "IDComprobante" : 3, "FechaComprobante" : "2023-05-16T00:00:00", "IDCliente" : 3, "Importe" : 14200, "Detalles" : [ { "IDDetalle" : 5, "IDProducto" : 5, "CantidadProducto" : 14, "ImporteUnitario" : 1000 } ] }

El valor resaltado en ROJO es el ETAG calculado para la versión actual del documento, el cual sirve para identificar a la misma.


A continuación, vamos a usar una sentencia UPDATE de SQL para actualizar en forma directa, en la tabla de detalles de comprobantes, el valor de la columna cantidad del registro de detalle #5, como vemos a continuación:

UPDATE tDetalleComprobante SET Cantidad = 7 WHERE ID_DetalleComprobante = 5;

1 row updated.


Volviendo al documento JSON que obtuvimos en el primer SELECT, asumamos ahora que la aplicación que lo obtuvo le hizo una modificación (por ejemplo, cambió el ID de cliente, como remarcamos en azul) y desea grabar dicho cambio, lo cual hace enviando el documento completo (incluyendo el ETAG que obtuvo al leer en documento) ejecutando la siguiente sentencia:

UPDATE vdComprobante c SET data = '{ "_metadata" : { "etag" : "66C4365F9A178623F27913B947DF8C7C", "asof" : "00000000007844AF" }, "IDComprobante" : 3, "FechaComprobante" : "2023-05-16T00:00:00", "IDCliente" : 500, "Importe" : 14200, "Detalles" : [ { "IDDetalle" : 5, "IDProducto" : 5, "CantidadProducto" : 14, "ImporteUnitario" : 1000 } ] }' WHERE c.data.IDComprobante = 3;


Al ejecutarla, obtendremos el siguiente mensaje de error:

Error report - ORA-42699: Cannot update JSON Relational Duality View 'VDCOMPROBANTE': The ETAG of document with ID 'FB03C10400' in the database did not match the ETAG passed in.


Esto se debe a que el ETAG del documento almacenado en la base de datos cambió al momento en que modificamos el detalle, lo cual podemos ver si volvemos a consultar el mismo:

SELECT JSON_SERIALIZE(c.data PRETTY) FROM VDCOMPROBANTE c WHERE c.data.IDComprobante = 3;


Obteniendo:

JSON_SERIALIZE(C.DATAPRETTY)
---------------------------------------------------------------- { "_metadata" : { "etag" : "5A94261D02F1232A3F126D7C36A961BD", "asof" : "00000000007848C6" }, "IDComprobante" : 3, "FechaComprobante" : "2023-05-16T00:00:00", "IDCliente" : 3, "Importe" : 14200, "Detalles" : [ { "IDDetalle" : 5, "IDProducto" : 5, "CantidadProducto" : 7, "ImporteUnitario" : 1000 } ] }


Con la versión "actualizada" del documento, la aplicación tiene que volver a aplicar el cambio individual deseado (actualizar el cliente) y volver a enviar todo el documento, con el ETAG que ahora si coincide con la versión almacenada en la base de datos.


Vistas del Diccionario de Datos

El diccionario de datos de Oracle 23 incorpora algunas nuevas vistas para acceder a la información de las vistas duales JSON Relacional. Veremos las mismas en detalle a continuación (analizaremos las visas que comienzan con USER_, que permiten acceder a los objetos del usuario conectado, existen versiones con prefijo ALL_ y DBA_ que ven todos los objetos sobre los que el usuario posee permisos y todos los objetos de la base de datos respectivamente).


USER_JSON_DUALITY_VIEWS

Esta vista contiene información general de cada JSON Relational Duality View definida en el esquema.

SELECT * FROM USER_JSON_DUALITY_VIEWS;


Las columnas ALLOW_INSERT, ALLOW_UPDATE y ALLOW_DELETE nos indican que tipo de acciones se pueden realizar sobre las mismas. La columna JSON_SCHEMA contiene el esquema JSON que describe al documento que esta disponible al utilizar cada una de las vistas.


USER_JSON_DUALITY_VIEW_TABS

Esta vista nos muestra la tabla principal y todas las tablas involucradas en cada una de las vistas duales:

SELECT * FROM USER_JSON_DUALITY_VIEW_TABS;


USER_JSON_DUALITY_VIEW_TAB_COLS

Esta vista muestra información sobre todas las columnas (atributos del documento JSON) definidas en una vista dual:

SELECT * FROM USER_JSON_DUALITY_VIEW_TAB_COLS;


La columna JSON_KEY_NAME nos indica el nombre de atributo en el documento JSON y las columnas PRIMARY_KEY_POSETAG_POS nos indica si forma parte de la clave primaria (y en que posición) y en que posición se encuentra dentro del ETAG.


USER_JSON_DUALITY_VIEW_LINKS

Esta vista nos permite entender las relaciones entre las distintas tablas en cada vista / documento JSON:

SELECT * FROM USER_JSON_DUALITY_VIEW_LINKS;


Conclusión

En este artículo hicimos un análisis del mecanismo de control de concurrencia optimista (sin lockeos) implementado en JSON Relational Duality Views y las vistas del diccionario de datos que contienen información


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.

jueves, 18 de mayo de 2023

APEX 23.1 Disponible en Oracle Cloud & On-Premise


Hace un mes anunciábamos en el artículo "Oracle APEX 23.1 (versión de pre-producción) disponible en apex.oracle.com" la disponibilidad de la nueva versión de Oracle APEX en el entorno  de pruebas gratuito apex.oracle.com y posteriormente explicamos las principales características de esta nueva versión en el artículo "Que hay de nuevo en APEX 23.1?".

Ayer Oracle anunció la disponibilidad de APEX 23.1 tanto en Oracle Cloud (se irá actualizando en las diversas regiones de OCI en el transcurso de la semana) como para ser descargada y usada On-Premise.

Por el momento, en la región de OCI de mi cuenta principal (Ashburn, Estados Unidos) todavía no se encuentra disponible (tampoco en otra instancia en San Pablo, Brasil):

Pero es de esperar que lo esté en pocos días, tal cual lo indica la pagina de novedades de APEX en Oracle Cloud:


Links Relacionados

A continuación los links para descargar la version para usarla on-premise y acceso a la documentación actualizada:


Nueva Funcionalidad - Hands On Labs

Están disponibles en el sitio de APEX un conjunto de tutoriales y laboratorios gratuitos para aprender a usar APEX!


Aplicaciones de Demo Actualizadas

Las aplicaciones de demo, disponibles en forma gratuita desde el sitio GitHub de Oracle APEX, fueron actualizadas para usar las mejoras disponibles en APEX 23.1.

martes, 16 de mayo de 2023

Oracle 23c & JSON - Relational Duality Views - Parte #1

La version 23c de la base de datos Oracle introduce muchas mejoras para trabajar con documentos JSON, en este artículo vamos a comenzar por una de las mas importantes, que es la disponibilidad de vistas "duales" para ver e interactuar con la información almacenada en nuestra base de datos en tablas relacionales pero directamente en formato JSON.

En el artículo vamos a utilizar dos tablas las cuales pueden crear para probar esta nueva funcionalidad usando el código a continuación:

CREATE TABLE tComprobante ( ID_Comprobante NUMBER(10) CONSTRAINT PK_Comprobante PRIMARY KEY, Fecha_Comprobante DATE NOT NULL, ID_Cliente NUMBER(10) NOT NULL, Importe DECIMAL (10,2) NOT NULL); -- CREATE TABLE tDetalleComprobante ( ID_DetalleComprobante NUMBER(10)
CONSTRAINT PK_DetalleComprobante PRIMARY KEY, ID_Comprobante NUMBER(10) NOT NULL
CONSTRAINT FK_DetalleComprobante_ID_Comprobante REFERENCES tComprobante(ID_Comprobante), ID_Producto NUMBER(10) NOT NULL, Cantidad NUMBER(10) NOT NULL, ImporteUnitario DECIMAL (10,2) NOT NULL);


Y también vamos a insertar algunos datos en las mismas, de la siguiente manera (aprovechando la nueva funcionalidad "Oracle 23c - Constructor de Tabla a partir de Valores"):

INSERT INTO tComprobante VALUES (1, DATE '2023-05-15', 1, 20500), (2, DATE '2023-05-15', 2, 9800), (3, DATE '2023-05-16', 3, 14200); -- INSERT INTO tDetalleComprobante VALUES (1, 1, 1, 20, 1000), (2, 1, 2, 5, 100), (3, 2, 3, 9, 1000), (4, 2, 4, 8, 100), (5, 3, 5, 14, 1000), (6, 3, 6, 2, 100); -- COMMIT;


Creando una Vista Dual JSON - Relacional

Vamos a crear una vista dual, la cual nos permite ver la información de varias tablas de nuestro sistema como si fuera un objeto JSON, usando la siguiente sintaxis:

CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW vdComprobante AS SELECT JSON {'IDComprobante' : c.ID_Comprobante, 'FechaComprobante' : c.Fecha_Comprobante, 'IDCliente' : c.ID_Cliente, 'Importe' : c.Importe , 'Detalles' : [ SELECT JSON {'IDDetalle' : d.ID_DetalleComprobante, 'IDProducto' : d.ID_Producto, 'CantidadProducto' : d.Cantidad, 'ImporteUnitario' : d.ImporteUnitario} FROM tDetalleComprobante d WITH INSERT UPDATE DELETE WHERE d.ID_Comprobante = c.ID_Comprobante ] } FROM tComprobante c WITH INSERT UPDATE DELETE;

La sintaxis es sencilla, en el ejemplo, estamos definiendo el mapeo entre las columnas de nuestras dos tablas (en verde) y los atributos del documento JSON (en naranja), y estamos permitiendo insertar, eliminar y actualizar registros de ambas tablas mediante la vista.


Usando una Vista Dual JSON - Relacional

Consultar Datos

Una vez que creamos la vista, podemos comenzar a usarla. Lo primero que vamos a hacer es consultar los datos disponibles en ella usando una sentencia SELECT:

SELECT * FROM vdComprobante;

Vemos que la vista posee una única columna, llamada DATA, la cual contiene un documento JSON representando a cada registro de nuestra tabla tComprobante y sus detalles asociados:


Tambien podemos usar la función JSON_SERIALIZE para obtener una representación mas "legible" del documento, usando la opción PRETTY de la misma, como mostramos a continuación:

SELECT JSON_SERIALIZE(c.data PRETTY) FROM vdComprobante c;


Nota: vemos que el documento contiene un elemento adicional llamado "_metadata" que vamos a explicar y analizar en un segundo artículo sobre JSON Relational Duality Views.


Podemos ver que la vista posee una única columna de tipo JSON si usamos el comando DESC para describir a la misma:

DESC vdComprobante

Name Null? Type ---- ----- ---- DATA JSON


Actualizar Datos

Las vistas duales no solo permiten ver los datos de nuestro modelo relacional como objetos JSON, sino que también podemos utilizarlas para actualizar datos tanto de la entidad principal (Comprobante) como de sus detalles usando un documento JSON. Probaremos de modificar la fecha del primer comprobante, y la cantidad y precio del primer item de dicho comprobante (nuevos valores resaltados en ROJO) , como vemos a continuación:

UPDATE vdComprobante c SET c.data = ( '{ "IDComprobante" : 1, "FechaComprobante" : "2023-05-14T00:00:00", "IDCliente" : 1, "Importe" : 20500, "Detalles" : [ { "IDDetalle" : 1, "IDProducto" : 1, "CantidadProducto" : 10, "ImporteUnitario" : 2000 }, { "IDDetalle" : 2, "IDProducto" : 2, "CantidadProducto" : 5, "ImporteUnitario" : 100 } ] }') WHERE c.data.IDComprobante = 1;

Nota: Usamos "dot notation" para referirnos a los elementos dentro del documento JSON almacenado en la columna data desde la sentencia SQL.


Tras ejecutar ese update sobre la vista, podemos ver que la fecha del comprobante fue actualizada y se ve reflejada así tanto en la table como en la vista dual:

SELECT ID_Comprobante, Fecha_Comprobante FROM tComprobante c WHERE c.ID_Comprobante = 1;
ID_COMPROBANTE FECHA_COMPROBANTE -------------- ------------------- 1 14-05-2023 00:00:00
SELECT c.data.IDComprobante, c.data.FechaComprobante
FROM vdComprobante c WHERE c.data.IDComprobante = 1;

IDCOMPROBANTE FECHACOMPROBANTE ------------------------------------------------------ ------------------------------------------------------ 1 "2023-05-14T00:00:00"


Lo mismo con las cantidades y precios del primer detalle:

SELECT d.ID_DetalleComprobante, d.Cantidad, d.ImporteUnitario FROM tDetalleComprobante d WHERE d.ID_DetalleComprobante = 1;

ID_DETALLECOMPROBANTE CANTIDAD IMPORTEUNITARIO --------------------- ---------- --------------- 1 10 2000


Eliminar Datos

Podemos eliminar datos usando directamente la vista, como se muestra en el ejemplo:

DELETE FROM vdComprobante c WHERE c.data.IDComprobante = 3;

1 row deleted.


La funcionalidad de DELETE sirve para eliminar todo el documento, si quisiéramos eliminar solamente un detalle de un comprobante tenemos que hacer un UPDATE sobre la vista enviando el documento JSON sin el registro de detalle que se desea eliminar, como podemos ver a continuación (previo a restaurar el comprobante #3 que eliminamos recién):

UPDATE vdComprobante c SET c.data = ( '{ "IDComprobante" : 3, "FechaComprobante" : "2023-05-16T00:00:00", "IDCliente" : 3, "Importe" : 14200, "Detalles" : [ { "IDDetalle" : 5, "IDProducto" : 5, "CantidadProducto" : 14, "ImporteUnitario" : 1000 } ] }') WHERE c.data.IDComprobante = 3;


Podemos validar que ahora el comprobante #3 posee un único item de la siguiente manera:

SELECT ID_DetalleComprobante, Cantidad, ImporteUnitario, ID_Producto FROM tDetalleComprobante d WHERE d.ID_Comprobante = 3;
ID_DETALLECOMPROBANTE CANTIDAD IMPORTEUNITARIO ID_PRODUCTO --------------------- ---------- --------------- ----------- 5 14 1000 5


Insertar Datos

Así como pudimos actualizar y eliminar, podemos insertar nuevos datos mediante las vistas duales. Si queremos insertar un detalle, en realidad debemos actualizar el documento con un detalle adicional, pero si queremos insertar un nuevo documento compuesto por un Comprobante y su detalle, usamos la sentencia SELECT como mostramos a continuación, y estaremos insertando datos en ambas tablas:

INSERT INTO vdComprobante c VALUES ( '{ "IDComprobante" : 4, "FechaComprobante" : "2023-05-16T00:00:00", "IDCliente" : 4, "Importe" : 6500, "Detalles" : [ { "IDDetalle" : 7, "IDProducto" : 7, "CantidadProducto" : 6, "ImporteUnitario" : 1000 } ] }');


Podemos validar el resultado de dicha operación con las siguientes consultas:

SELECT ID_Comprobante, Fecha_Comprobante FROM tComprobante c WHERE c.ID_Comprobante = 4;
ID_COMPROBANTE FECHA_COMPROBANTE -------------- ------------------- 4 16-05-2023 00:00:00

SELECT ID_DetalleComprobante, Cantidad, ImporteUnitario, ID_Producto FROM tDetalleComprobante d WHERE d.ID_Comprobante = 4;

ID_DETALLECOMPROBANTE CANTIDAD IMPORTEUNITARIO ID_PRODUCTO --------------------- ---------- --------------- ----------- 7 6 1000 7


Conclusión

En este artículo hicimos un análisis inicial de la funcionalidad de JSON - Relational Duality Views que seguiremos explorando en los próximos días, así como otras importantes mejoras a JSON disponibles en Oracle Database 23c 


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.



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.



viernes, 5 de mayo de 2023

Oracle 23c - Soporte de tipo de datos DATE, TIMESTAMP e INTERVAL en funciones CEIL y FLOOR

Otra interesante mejora en Oracle 23c es la posibilidad de usar las funciones FLOOR y CEIL (las cuales devuelven el valor redondeado hacia abajo o hacia arriba) con los tipos de datos DATE, TIMESTAMP e INTERVAL, además de usarlas con datos numéricos como era posible hasta ahora.


Nota: para poder ver los resultados correctos de los ejemplos mostrados en el artículo, es recomendable configurar las variables de sesión de formato de fecha de la siguiente manera:

ALTER SESSION SET nls_date_format='DD-MM-YYYY HH24:MI:SS'; ALTER SESSION SET nls_timestamp_format='DD-MM-YYYY HH24:MI:SS.FF3';


FLOOR y CEIL con DATE

En el siguiente ejemplo, vamos a mostrar el uso de ambas funciones con el tipo de datos DATE. La sintaxis mas sencilla es la siguiente:

SELECT SYSDATE AS Fecha_Hora,
    FLOOR(SYSDATE) AS FLOOR_SYSDATE,
    CEIL(SYSDATE) AS CEILING_SYSDATE;

Y al ejecutar la misma obtenemos el siguiente resultado:


Ambas funciones permiten el uso de un modificador de formato, en el cual podemos especificar si queremos redondear (hacia arriba o hacia abajo) con una unidad de medida distinto al valor por defecto que, como toda la aritmética de fechas en Oracle, se basa en días. El ejemplo siguiente muestra como redondear hacia abajo en minutos y como redondear hacia arriba en horas:

SELECT SYSDATE AS Fecha_Hora,
    FLOOR(SYSDATE, 'MI') AS FLOOR_SYSDATE,
    CEIL(SYSDATE, 'HH24') AS CEILING_SYSDATE;

Podemos ver el resultado de ejecutar la sentencia:


Nota
: para ver los formatos aceptados por estas funciones ver el artículo CEIL, FLOOR, ROUND, and TRUNC Date Functions en la documentación oficial.


FLOOR y CEIL con TIMESTAMP

La sintaxis es exactamente igual, y podemos ver el mismo ejemplo usando modificadores de formato pero esta vez con el tipo de dato TIMESTAMP:

SELECT CURRENT_TIMESTAMP AS Fecha_Hora,
    FLOOR(CURRENT_TIMESTAMP,'MI') AS FLOOR_TIMESTAMP,
    CEIL(CURRENT_TIMESTAMP,'HH24') AS CEILING_TIMESTAMP;

Obteniendo estos resultados:


Nota: ambas funciones aceptan valores de entrada de tipo TIMESTAMP, pero devuelven valores de tipo DATE, como se ve en la imagen al no incluir fracciones de segundos.


FLOOR y CEIL con INTERVAL

Por último, vamos a aplicar las funciones a datos de tipo INTERVAL, para ellos usamos una CTE que simula una tabla con una columna de este tipo de datos, y le aplicamos ambas funciones con modificadores de formato para redondear a minutos hacia abajo y redondear a horas hacia arriba:

WITH vData AS (SELECT INTERVAL '0 05:23:14.333' DAY TO SECOND AS Intervalo) SELECT Intervalo,
    FLOOR(Intervalo,'MI') AS FLOOR_INTERVAL,
    CEIL(Intervalo,'HH24') AS CEILING_INTERVAL FROM vData;

Obteniendo el siguiente resultado:


Conclusión

Si bien la función FLOOR puede reemplazarse sin problemas por TRUNC (en todos los ejemplos mencionados devuelve el mismo resultado) la posibilidad de usar la misma así como usar CEILING con tipos de datos adicionales a los numéricos es una ventaja que facilita el desarrollo de código SQL a partir de Oracle 23c.


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.