Olá a todos,
Estou desenvolvendo uma estrutura de dados que necessita de algumas restrições que não podem ser explicitadas com elegância através de contraints check. Portanto, decidi utilizar triggers para resolver o problema, porém, no SGBD que estou utilizando a solução se tornou mais deselegante ainda (rs).
Enfim, necessito checar determinada condição com os novos dados a serem inseridos no banco e caso determinada condição não seja satisfeita preciso interromper a inserção. No entanto, desconheço algum comando do MySQL 5.1 que efetue tal tarefa, ou seja, interromper uma inserção.
Contudo, resolvi o problema com a seguinte trigger (o que não me deixo muito feliz):
DELIMITER $$
USE `REUNIOES`$$
CREATE TRIGGER checkTypeValue
BEFORE INSERT ON Reuniao
FOR EACH ROW
BEGIN
IF ( NEW.idConselho <> 2 AND NEW.tipo NOT IN ( 'O', 'E' ) ) THEN
SET NEW.tipo := NULL;
END IF;
END $$
DELIMITER ;
Ou seja, para interromper a inserção atribuo a flag NULL para um atributo obrigatório (POG).
Caso alguém conheça alguma solução mais elegante para esse problema, por favor, me informem.
Olá,
Você não possui objetos que realizam as funções de persistência (DAOs)?
Se sim, você faria essa verificação no método “adicionar” da entidade que deseja gravar.
Se não, a própria documentação do MySQL recomenda o uso de Triggers em casos onde você precisa trabalhar com várias linguagens acessando o mesmo banco (17.2 no manual), se esse não for o seu caso acho que seria interessante usar DAOs
[ ]'s
Ev3rton, o ideal nem seria fazer esta validação na DAO, mas, numa camada de negócios. Assim se trava as chamadas desnecessárias à recursos mais específicos.
Caso contrário e, sendo o mesmo o desenvolvedor do banco, poderia resolver com uma simples stored procedure, validando as entradas (já que está deselegante) e, claro, caso fosse preciso ou já existisse uma trigger. Assim sendo, a trigger se torna a solução mais adequada. Não sei por que este medo de utilizar esta ferramenta…
Olá Pessoa,
Primeiramente muito obrigado pela atenção Ev3rton e drsmachado.
Sobre a resposta do Ev3rton: eu utilizo sim DAOs e faço as validações como descrito pelo drsmachado (na camada de negócios) [estou utilizando Hibernate e Spring para desenvolver o software], porém, realmente a validação que desejo é de extrema importância para a integridade dos dados, sendo assim, julgo de responsabilidade do banco mantê-lo integro.
Sobre a resposta do drsmachado: importante seu comentário sobre as stored procedure, porém, não seria muito limpo inserir uma tupla através de uma SP já que é uma validação muito simples, o que pode ser resolvido com uma trigger. Muito obrigado pela resposta.
Agora sobre a solução atual: pesquisei um pouco mais e desenvolvi a seguinte solução:
DELIMITER $$
USE `REUNIOES`$$
CREATE TRIGGER checkTypeValue
BEFORE INSERT ON Reuniao
FOR EACH ROW
BEGIN
DECLARE dummy INT;
IF ( NEW.idConselho <> 2 AND NEW.tipo NOT IN ( 'O', 'E' ) ) THEN
SET NEW := "The type of the meeting is not valid";
END IF;
END $$
DELIMITER ;
Ainda não é elegante o suficiente, porém, quando há um erro a seguinte resposta é emitida:
#1231 - Variable 'new' cannot be set to the value of 'The type of the meeting is not valid'
Esse proposta pelo menos exibe alguma mensagem que ajudará o usuário a encontrar o motivo do erro. Mas para mim, o melhor seria o MySQL 5.1 conter recursos como:
throw new Exception( "The type of the meeting is not valid" );
Isso resolveria o meu problema com muita elegância.
Muito obrigado pela ajuda, qualquer outra sugestão será muito bem vinda.
Na versão 5.1 do MySQL não tem mas, na versão 5.6 existe o seguinte:
SIGNAL STATE '45000' SET MESSAGE_TEXT = '<SUA MENSAGEM>';
O código 45000 é para mensagens customizadas, existem outros códigos para outros erros já mapeados.
DELIMITER $$
USE `REUNIOES`$$
CREATE TRIGGER checkTypeValue
BEFORE INSERT ON Reuniao
FOR EACH ROW
BEGIN
DECLARE dummy INT;
IF ( NEW.idConselho <> 2 AND NEW.tipo NOT IN ( 'O', 'E' ) ) THEN
SIGNAL STATE '45000' SET MESSAGE_TEXT = 'The type of the meeting is not valid';
END IF;
END $$
DELIMITER ;