Um recurso muito interessante, mas pouco utilizado em constraints, é o de constraints postergáveis (adiáveis) ou DEFERRABLE CONSTRAINTS.
Por padrão, CONSTRAINTS são validadas (aplicadas e verificadas) no momento em que uma instrução DML (INSERT, UPDATE ou DELETE) é executada no Banco de Dados. No caso de uma instrução INSERT, por exemplo, no momento em que ela é executada, se um valor fornecido para uma coluna que tenha uma CONSTRAINT for um valor que viole a regra ou condição imposta pela CONSTRAINT, a instrução irá retornar um erro. Deste modo, sempre que uma instrução violar uma CONSTRAINT ela irá gerar um erro "imediatamente", ou seja, a instrução será validada sempre no momento de sua execução.
É possível postergar ou adiar a validação da CONSTRAINT para o momento do término da transação em que uma instrução está contida. Em outras palavras, quando temos DEFERRABLE CONSTRAINTS, a validação da CONSTRAINT só ocorre no momento em que a transação finalizar (após um COMMIT ou ROLLBACK). Uma transação poderá conter múltiplas instruções. Não importa quantas instruções ela tenha, se a CONSTRAINT for postergável, ela será validada somente no término da transação.
DEFERRABLE CONSTRAINTS são úteis em casos tais como:
1- Na atualização de 2 tabelas que possuem relacionamento, onde precisamos incluir uma linha nova, primeiro na tabela que contém a chave-estrangeira (tabela filha) e depois na tabela que contém a chave-primária do relacionamento (tabela mãe).
Ex.: INSERT INTO EMPREGADO (ID, NOME, DEPARTAMENTO_ID) VALUES (103, 'FÁBIO PRADO', 23);
INSERT INTO DEPARTAMENTO (DEPARTAMENTO_ID, NOME) VALUES (23, 'TI');
COMMIT;
Obs.: Neste caso, considerando que existe uma DEFERRABLE CONSTRAINT de chave-estrangeira na coluna DEPARTAMENTO_ID da tabela EMPREGADO referenciando a coluna ID na tabela DEPARTAMENTO, a transação contendo as 2 instruções INSERT seria executada com sucesso. Se a CONSTRAINT fosse criada no modo padrão (imediato), ao executar a primeira instrução INSERT (na tabela EMPREGADO) um erro ocorreria.
2- Na inserção de dados em massa. Ao submeter comandos para inserir, por exemplo, milhares de linhas em uma tabela, o processo de inserção ocorre mais rápido se a checagem das constraints for executada somente no final, de uma única vez.
Ao criar uma CONSTRAINT do tipo DEFERRABLE é possível definir que a postergação da validação esteja inicialmente desabilitada, ou seja, ela será validada imediatamente, no momento da execução de uma instrução (não no final da transação).
Ex.: CREATE TABLE EMPREGADO ( ID NUMBER,
NOME VARCHAR2(30),
DEPARTAMENTO_ID NUMBER,
CONSTRAINT EMP_PK PRIMARY KEY (ID), CONSTRAINT EMP_DEPTO_FK FOREIGN KEY (DEPARTAMENTO_ID)
REFERENCES DEPARTAMENTO (DEPARTAMENTO_ID)
DEFERRABLE INITIALLY IMMEDIATE);
ou é possível definir que ela esteja inicialmente habilitada, ou seja, que ela será validada somente no término da transação:
CREATE TABLE EMPREGADO ( ID NUMBER, NOME VARCHAR2(30), DEPARTAMENTO_ID NUMBER, CONSTRAINT EMP_PK PRIMARY KEY (ID), CONSTRAINT EMP_DEPTO_FK FOREIGN KEY (DEPARTAMENTO_ID) REFERENCES DEPARTAMENTO (DEPARTAMENTO_ID) DEFERRABLE INITIALLY DEFERRED);
A qualquer momento é possível alterar o "comportamento" DEFERRABLE da CONSTRAINT:
a) Se for desejado alterar para validar imediatamente (sem postergação):
SET CONSTRAINTS EMP_DEPTO_FK IMMEDIATE;
b) Se for desejado alterar para validar somente no final da transação (com postergação):
SET CONSTRAINTS EMP_DEPTO_FK DEFERRED;
Bom pessoal, por hoje é só!
[]s
Colega, obrigado pelo post, estou estudando para concurso e tinha uma questão com esse comando e nunca tinha puvido falar.
ResponderExcluirabs
Legal, em qual concurso caiu questão sobre este assunto?
ExcluirObrigado!
ResponderExcluirPost muito bem explicado!
Orlando, eu é quem agradeço o seu comentário!
ExcluirExcelente post. Claro e objetivo! parabéns!!
ResponderExcluirVictor, obrigado pelo comentário.
ExcluirExplicação direta. Simples e eficiente!!
ResponderExcluirObrigado pelo comentário!
Excluir[]s
Fábio, sua didática impressiona pela simplicidade e eficiência. Parabéns!
ResponderExcluirMuito Obrigado pelo feedback!
ExcluirExplicação extremamente clara.
ResponderExcluirValeu!
Renato, obrigado pelo feedback!
Excluir