Oracle Database 12c: "Nuevas Características para Desarrolladores" ( Parte I )

Por Joel Pérez & Mahir M. Quluzade (OCP)
Publicado en Septiembre 2014

Reciban estimados tecnólogos Oracle un cordial saludo. A través del presente artículo, tendremos la oportunidad de visualizar y adentrarnos un poco en algunas de las nuevas características que trajo consigo la nueva versión de base de datos ( BBDD ) "Oracle Database 12c"

En esta nueva versión han sido incorporado extensas nuevas características pertenecientes a diversas aéreas, el siguiente articulo estará enfocado a nuevas características relacionadas con tareas y técnicas muy cercanas a la actividad regular de desarrolladores.

Hemos organizado algunas de las nuevas características por áreas e iremos desarrollando las mismas a través del contenido de varios artículos de esta serie:

Nuevas Características a nivel de:

  • "Schema"
  • "Optimizer"
  • "PL/SQL"
  •  Fácil migración de Código a Oracle
  • "SQL"
  •  Utilitarios
  • "Transaction Guard"
  • "Information Lifeycle Management"
  • "Partitioning"

Iniciemos..

"Invisible Columns"

"Ocultar el cambio hasta que estemos listos para ello" bajo esta filosofía y metodología de trabajo funciona una de las nuevas características denominadas "Invisible Columns" ( Columnas Invisibles ). En "Oracle Database 11g" emergieron numerosas nuevas características entre las cuales se encontraba la de los "Indices Invisibles". Los índices invisibles estaban basados en la posibilidad de crear índices que no fuesen parte del funcionamiento activo para los planes de ejecución más si constituía un segmento con políticas de mantenimiento como cualquier otro índice. Esta concepción permitía la creación de segmentos que estuvieran listos para un cambio efectivo de elementos en producción pero con la particularidad de que los mismos entrarían en funcionamiento al llevar un ligero cambio de configuración en el mismo, permitiendo así la capacidad de introducir un cambio y reducir al mínimo los efectos secundarios negativos del mismo. El "core" conceptual de lo recientemente explicado, aplica también para la nueva característica de "Columnas Invisibles". Entonces, como funcionan las "Columnas Invisibles" ?

Regularmente cuyo se agrega una columna a una tabla, cualquier programa con una instrucción SELECT * sería capaz de visualizar esa columna. Programas con una valores INSERT INTO T (...) obtendrían errores de ejecución al poseer un comyo de INSERT sin una lista explicita de columnas. Con la nueva característica, podemos agregar una columna a una tabla de una manera invisible, teniendo el siguiente comportamiento:

  • La columna no se mostrará en un comyo DESCRIBE de SQL * Plus
  • Los valores de dicha columna no serán retornados con un "SELECT *"
  • La columna no será considerada para valores en operaciones "INSERT INTO..."
  • Los valores de la columna nueva se podrán acceder por cualquier consulta que solicite explícitamente el mismo
  • La tabla podrá ser objeto de una instrucción "INSERT" que incluya la columna siempre y cuyo se haga referencia explicita a la misma

Ejecutemos algunas sentencias para visualizar la operación de esta nueva característica:

Creación de una tabla sencilla denominada "mytable" con dos campos:




SQL> create table mytable
2 ( c1 number(3),
3 c2 number(3)
4 )
5 /
Table created.

SQL> insert into mytable values ( 350, 560 );

1 row created.
SQL> commit;

Adición de un campo en modo invisible:

SQL> alter table mytable add ( c3 number(3) INVISIBLE );

Visualización al ejecutar una operación de "describe". La columna no es mostrada a pesar de que esta creada tal fue descrito en las características de operación en párrafos anteriores




SQL> desc t

Name Null? Type
---- ----- ----------
C1 NUMBER(3)
C2 NUMBER(3)


Visualización al ejecutar una operación de "describe" previo habilityo la capacidad de ver columnas invisibles:




SQL> set colinvisible on
SQL> desc t

Name Null?                Type
----      -----                 ----------
C1                            NUMBER(3)
C2                           NUMBER(3)
C3      (INVISIBLE) NUMBER(3)



Si ejecutamos un "SQL Statement Select" a la tabla, la columna no se visualizara:




SQL> select * from mytable;

X             Y
------------ --------
350         560

Una vez que el cambio en aplicaciones este listo para formar parte del ambiente productivo de forma activa. Aplicamos el cambio a modo visible de la columna y efectuado esto, la misma estará disponible para todos los usuarios regulares de BBDD:




SQL> alter table mytable modify c3 visible;
Table altered.

SQL> select * from mytable;

X            Y        Z
----------- ------- ----------
350       560


Una vez realizado el cambio los usuarios podrán acceder a la escritura de la columna nueva:



SQL> insert into mytable values ( 700, 800, 900 );

1 row created.
SQL> commit;
SQL> select * from mytable;

X            Y        Z
----------- ------- ----------
350        560
700        800    900

Es importante destacar es possible insertar valores para la columna invisible antes de que esta pase a su estado visible siempre y cuyo el "Insert" suministre la referencia explicita de la columna en su operación de "Insert".

Pasemos a otra nueva caracteristica denominada:

"Default Values using Secuences"

En "Oracle Database 12c" es posible utilizar diversos valores por defectos para las columnas. Dichos valores pueden estar asociados a diversos elementos, en este caso resaltaremos el uso de valores por defecto basados en secuencias. Para utilizarlo en esta nueva características solo es necesario colocar la referencia de una secuencia en la definición de la columna en conjunto con la clausula "Default".

Notas de uso:

  • Select: Durante la creación de la tabla la secuencia debe existir y se debe poseer privilegio de "Select" sobre la misma para poder ser utilizada en la clausula de una columna.
  • Privilegio para "Insert": los usuarios que deseen insertar sobre la tabla deben poseer privilegio de "Select" sobre la secuencia y los regulares permisos de inserción sobre la tabla
  • Veamos algunos ejemplos de esta nueva característica.

Creación de una secuencia "mytable_seq" y la tabla "mytable" con el uso de la secuencia en operatividad "NEXTVAL" para el campo C1:




CREATE SEQUENCE mytable_seq;

CREATE TABLE mytable (
C1 NUMBER DEFAULT mytable_seq.NEXTVAL,
C2 VARCHAR2(50));

Creación de una secuencia "mytable_seq" y la tabla "mytable" con el uso de la secuencia en operatividad "NEXTVAL" para el campo C1:




CREATE SEQUENCE mytable_seq;

CREATE TABLE mytable (
C1 NUMBER DEFAULT mytable_seq.NEXTVAL,
C2 VARCHAR2(50));

Realizaremos 3 "Inserts" lo cuales realizan lo siguiente respectivamente:

  • "Insert" especificyo solo el campo "C2", al no incluir el campo "C1" relacionado con la secuencia. Su valor será controlado por la misma
  • "Insert" con valores explícitos para todos los campos. En dicho caso el campo "C2" no accede a su funcionalidad relacionada con la secuencia
  • "Insert" con valores explícitos para todos los campos, con valor "NULL" para "C1" ( campo relacionado con la secuencia ). En dicho caso el valor final del campo sera "NULL"



INSERT INTO mytable (C2) VALUES ('C2 solamente');
INSERT INTO mytable (C1, C2) VALUES (100, 'C1=100 y C2');
INSERT INTO mytable (C1, C2) VALUES (NULL, 'C1 en Null y C2');

En líneas generales, el campo relacionado con la secuencia obtendrá valor de la misma cuyo el mismo no es incluido en la sentencia de "Insert".

 "Identity Columns"

Una columna puede ser identificada como "Identity" lo cual implica una asociación de secuencia generada por el manejador. El usuario debe poseer privilegios para crear tablas y secuencias.
La sintaxis de uso es la siguiente:



GENERATED
[ ALWAYS | BY DEFAULT [ ON NULL ] ]
AS IDENTITY [ ( identity_options ) ]


Veamos 3 variaciones de uso de la misma:

Caso 1: con la clausula "ALWAYS" se hace uso forzado de la identidad. Si una sentencia de "INSERT" hace referencia a la columna se generara un error indiferentemente de cual sea el valor incluyendo inclusive "NULL".




SQL> CREATE TABLE mytable (
id NUMBER GENERATED ALWAYS AS IDENTITY,
descripcion VARCHAR2(30));

SQL> INSERT INTO mytable (descripcion) VALUES ('Just DESCRIPCION');

1 row created.

SQL> INSERT INTO mytable (id, descripcion) VALUES (NULL, 'ID=NULL y DESCRIPCION');
INSERT INTO mytable (id, descripcion) VALUES (NULL, 'ID=NULL y DESCRIPCION')
*
ERROR at line 1:
ORA-32795: cannot insert into a generated always identity column

SQL> INSERT INTO mytable (id, descripcion) VALUES (500, 'ID=500 y DESCRIPCION');
INSERT INTO mytable (id, descripcion) VALUES (500, 'ID=500 y DESCRIPCION')
*
ERROR at line 1:
ORA-32795: cannot insert into a generated always identity column

SQL>




Caso 2: con la clausula "BY DEFAULT" se permite la inserción de valores explícitos no asociados a la identidad. En caso de no hacer referencia a ningún valor, el valor introducido será el asociado a la identidad. La especificación de valor "NULL" arrojara error de ejecución.




CREATE TABLE mytable (
id NUMBER GENERATED BY DEFAULT AS IDENTITY,
descripcion VARCHAR2(30));

SQL> INSERT INTO mytable (descripcion) VALUES ('Just DESCRIPCION');

1 row created.

SQL> INSERT INTO mytable (id, descripcion) VALUES (500, 'ID=500 y DESCRIPCION');

1 row created.

SQL> INSERT INTO mytable (id, descripcion) VALUES (NULL, 'ID=NULL y DESCRIPCION');
INSERT INTO mytable (id, descripcion) VALUES (NULL, 'ID=NULL y DESCRIPCION')
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("OCM"."MYTABLE"."ID")

SQL>

Caso 3: con la clausula "BY DEFAULT ON NULL" se permite la inserción de valores explícitos no asociados a la identidad. En caso de no hacer referencia a ningún valor, el valor introducido será el asociado a la identidad. La especificación de valor "NULL" accionara el uso por defecto de la identidad.




CREATE TABLE mytable (
id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
descripcion VARCHAR2(30)
);

SQL> INSERT INTO mytable (descripcion) VALUES ('solo DESCRIPCION');

1 row created.

SQL> INSERT INTO mytable (id, descripcion) VALUES (500, 'ID=500 y DESCRIPCION');

1 row created.

SQL> INSERT INTO mytable (id, descripcion) VALUES (NULL, 'ID=NULL y DESCRIPCION');

1 row created.

SQL> SELECT * FROM mytable;

ID DESCRIPCION
---------- ------------------------------
1 solo DESCRIPCION
500 ID=500 y DESCRIPCION
2 ID=NULL y DESCRIPCION

SQL>

De esta manera hemos concluido la primera entrega de esta serie de artículos de nuevas características para desarrolladores bajo "Oracle Database 12c".

Como siempre, esperamos que el articulo sea de agrado y utilidad. Nos vemos en los próximos.

Saludos.

Joel es un experto DBA con más de 12 años de experiencia, especializado en bases de datos con especial énfasis en la soluciones de alta disponibilidad (RAC, Data Guard, y otras). Es un conferencista habitual en eventos de Oracle como: OTN LAD TOUR y otros. Consultor Internacional con trabajos en más de 20 países alrededor del mundo. Fue el primer latinoamericano en ser nombrado "Experto OTN" en el año 2003, Oracle ACE año 2004 y actualmente Oracle ACE Director.

Mahir es un Senior DBA con mas de 10 anos de experiencia en bases de datos Oracle con especial foco en "High Availability" & "Disaster Recovery Solutions (RAC, Data Guard, RMAN,…)". Mahir actualmente trabaja en el "Central Bank of the Republic of Azerbaijan". El es OCP DBA. Mahir es frecuente orador en el "Azerbaijan Oracle User Group (AZEROUG)".