Para grande frustração dos administradores de banco de dados em todo o mundo, antes da versão 12c do Oracle em meados de 2014, a Oracle simplesmente não tinha capacidade inerente de gerar colunas de incremento automático dentro de um esquema de tabela. Embora as razões para essa decisão de design possam ser apenas adivinhadas, a boa notícia é que, mesmo para usuários de sistemas Oracle mais antigos, existe uma solução alternativa para contornar essa armadilha e criar sua própria coluna de chave primária auto-incrementada.
Criando uma sequência
O primeiro passo é criar uma
SEQUENCE
em seu banco de dados, que é um objeto de dados que vários usuários podem acessar para gerar valores incrementados automaticamente. Conforme discutido na documentação, uma sequência no Oracle impede que valores duplicados sejam criados simultaneamente porque vários usuários são efetivamente forçados a “revezar” antes que cada item sequencial seja gerado. Para fins de criação de uma chave primária exclusiva para uma nova tabela, primeiro devemos
CREATE
a tabela que usaremos:CREATE TABLE books (
id NUMBER(10) NOT NULL,
title VARCHAR2(100) NOT NULL
);
Em seguida, precisamos adicionar uma
PRIMARY KEY
limitação:ALTER TABLE books
ADD (
CONSTRAINT books_pk PRIMARY KEY (id)
);
Por fim, criaremos nossa
SEQUENCE
que será utilizado mais tarde para realmente gerar o valor único e incrementado automaticamente. CREATE SEQUENCE books_sequence;
Adicionando um gatilho
Enquanto temos nossa tabela criada e pronta para ser usada, nossa sequência até agora está apenas parada lá, mas nunca sendo colocada em uso. É aqui que
TRIGGERS
entre. Semelhante a um
event
em linguagens de programação modernas, um TRIGGER
no Oracle é um procedimento armazenado que é executado quando ocorre um determinado evento. Normalmente um
TRIGGER
será configurado para disparar quando uma tabela for atualizada ou um registro for excluído, fornecendo um pouco de limpeza quando necessário. No nosso caso, queremos executar nosso
TRIGGER
antes de INSERT
em nossos books
tabela, garantindo nossa SEQUENCE
é incrementado e esse novo valor é passado para nossa coluna de chave primária. 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;
Aqui estamos criando (ou substituindo se existir) o
TRIGGER
chamado books_on_insert
e especificando que queremos que o gatilho dispare BEFORE INSERT
ocorre para os books
tabela, e para ser aplicável a todas e quaisquer linhas nela. O 'código' do gatilho em si é bastante simples:Nós
SELECT
o próximo valor incremental do nosso books_sequence
criado anteriormente SEQUENCE
, e inserindo-o no :new
registro dos books
tabela no .id
especificado campo. Observação:o
FROM dual
parte é necessária para concluir uma consulta adequada, mas é efetivamente irrelevante. O dual
table é apenas uma única linha fictícia de dados e é adicionada, neste caso, apenas para que possa ser ignorada e, em vez disso, possamos executar a função de sistema do nosso gatilho em vez de retornar dados de algum tipo. Colunas de IDENTIDADE
IDENTITY
colunas foram introduzidas no Oracle 12c, permitindo a funcionalidade de incremento automático simples nas versões modernas do Oracle. Usando a
IDENTITY
coluna é funcionalmente semelhante à de outros sistemas de banco de dados. Recriando nossos books
acima esquema de tabela no Oracle 12c moderno ou superior, simplesmente usaríamos a seguinte definição de coluna. CREATE TABLE books (
id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
title VARCHAR2(100) NOT NULL
);