Para gran frustración de los administradores de bases de datos de todo el mundo, antes de la versión 12c de Oracle a mediados de 2014, Oracle simplemente no tenía la capacidad inherente de generar de forma inherente columnas de incremento automático dentro de un esquema de tabla. Si bien las razones de esta decisión de diseño solo se pueden adivinar, la buena noticia es que incluso para los usuarios de sistemas Oracle más antiguos, existe una posible solución para sortear este escollo y crear su propia columna de clave principal incrementada automáticamente.
Creando una Secuencia
El primer paso es crear una SEQUENCE
en su base de datos, que es un objeto de datos al que múltiples usuarios pueden acceder para generar automáticamente valores incrementados. Como se explica en la documentación, una secuencia en Oracle evita que se creen valores duplicados simultáneamente porque varios usuarios se ven obligados a "tomar turnos" antes de que se genere cada elemento secuencial.
A los efectos de crear una clave primaria única para una nueva tabla, primero debemos CREATE
la tabla que usaremos:
CREATE TABLE books (
id NUMBER(10) NOT NULL,
title VARCHAR2(100) NOT NULL
);
A continuación, debemos agregar una PRIMARY KEY
restricción:
ALTER TABLE books
ADD (
CONSTRAINT books_pk PRIMARY KEY (id)
);
Finalmente, crearemos nuestra SEQUENCE
que se utilizará más tarde para generar realmente el valor incrementado automático único.
CREATE SEQUENCE books_sequence;
Agregar un disparador
Si bien tenemos nuestra tabla creada y lista para funcionar, nuestra secuencia hasta ahora está sentada allí pero nunca se ha puesto en uso. Aquí es donde TRIGGERS
entra.
Similar a un event
en los lenguajes de programación modernos, un TRIGGER
en Oracle es un procedimiento almacenado que se ejecuta cuando ocurre un evento en particular.
Normalmente un TRIGGER
se configurará para activarse cuando se actualice una tabla o se elimine un registro, proporcionando un poco de limpieza cuando sea necesario.
En nuestro caso, queremos ejecutar nuestro TRIGGER
antes de INSERT
en nuestros books
tabla, asegurando nuestra SEQUENCE
se incrementa y ese nuevo valor se pasa a nuestra columna de clave principal.
CREATE OR REPLACE TRIGGER books_on_insert
BEFORE INSERT ON books
FOR EACH ROW
BEGIN
SELECT books_sequence.nextval
INTO :new.id
FROM dual;
END;
Aquí estamos creando (o reemplazando si existe) el TRIGGER
llamado books_on_insert
y especificando que queremos que el activador se dispare BEFORE INSERT
ocurre para los books
tabla, y ser aplicable a todas y cada una de las filas de la misma.
El 'código' del activador en sí es bastante simple:SELECT
el siguiente valor incremental de nuestro books_sequence
creado previamente SEQUENCE
, e insertándolo en el :new
registro de los books
tabla en el .id
especificado campo.
Nota:El FROM dual
parte es necesaria para completar una consulta adecuada, pero es irrelevante en la práctica. El dual
table es solo una única fila ficticia de datos y se agrega, en este caso, solo para que pueda ignorarse y, en su lugar, podamos ejecutar la función del sistema de nuestro activador en lugar de devolver datos de algún tipo.
Columnas IDENTIDAD
IDENTITY
Las columnas se introdujeron en Oracle 12c, lo que permite una funcionalidad de incremento automático simple en las versiones modernas de Oracle.
Usando la IDENTITY
La columna es funcionalmente similar a la de otros sistemas de bases de datos. Recreando nuestros books
anteriores esquema de tabla en Oracle 12c moderno o superior, simplemente usaríamos la siguiente definición de columna.
CREATE TABLE books (
id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
title VARCHAR2(100) NOT NULL
);