Marcos S. 0 Denunciar post Postado Fevereiro 18, 2014 Olá pessoal! tudo certo?Preciso de uma pequena ajuda de vocês!Tenho um banco de dados onde contém a tabela "Motorista". Nela, existem os campos "codEmpresa" (referenciada como chave a tabela principal "Empresa") e "lider" (campo do tipo BIT) que devemos analisar. Como mostra abaixo: Preciso criar uma TRIGGER UPDATE que faça a seguinte condição: - Não é permitido mais de um "lider" por "codEmpresa", ou seja, deve ficar nesta mesma condição em destaque na imagem acima. - Se um outro "lider" for alterado para 1, o antigo lider deve ser 0 automaticamente. Para isso estava tentando criar uma TRIGGER AFTER UPDATE, como mostra abaixo: [inline]USE `tms`;DELIMITER $$CREATE DEFINER=`root`@`%` TRIGGER tg_lider_unico_update AFTER UPDATE ON tms.motoristaFOR EACH ROWBEGINIF EXISTS (SELECT m.lider FROM tms.motorista m, NEW WHERE m.codEmpresa = NEW.codEmpresa GROUP BY m.codEmpresa HAVING SUM(m.lider) > 1) THENSET NEW.lider = 1;SET OLD.lider = 0;END IF;END[/inline] Talvez tenha errado feio em como fazer, mas dessa maneira não funciona! Porque "NEW" não é suportado por AFTER UPDATE e se for fazer por BEFORE UPDATE, é acusado que "OLD" não é suportado. Como solucionar? Agradeço desde já pela ajuda! Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Fevereiro 18, 2014 Nao permitir dois lideres creio que dá numa trigger de before insert /update que verifique se nao existe outro lider, existindo gera um erro. Atualizar o outro pode cair num caso de mutant table Compartilhar este post Link para o post Compartilhar em outros sites
paulojuchem 20 Denunciar post Postado Fevereiro 19, 2014 USE `tms`; DELIMITER $ CREATE DEFINER=`root`@`%` TRIGGER tg_lider_unico_update BEFORE UPDATE ON tms.motorista FOR EACH ROW BEGIN IF (SELECT m.lider FROM tms.motorista m WHERE m.codEmpresa = NEW.codEmpresa AND m.lider = 1) IS NOT NULL AND NEW.lider=1 THEN --aqui sabemos que para aquela empresa existe um lider e que estamos tentando atualizar outro registro para que ele seja o lider,lembre-se que essa trigger é before update UPDATE tms.motorista SET lider=0 WHERE codEmpresa=NEW.codEmpresa; --pronto, nao tem mais ngm como lider na empresa, agora é só deixar que o update prossiga pra que um novo lider seja selecionado END IF; END EDIT: para o insert vc pode usar uma logica semelhante EDIT2: achei massa como vc interpretou o OLD, heheh O OLD e o NEW dentro da trigger se referem ao(aos) registro(s) que vc esta atualizando, vamos supor que vc esteja atualizando o registro 2, o OLD vai pegar o valor antigo da linha e o NEW os novos que vc quer colocar nela. se vc usar SET OLD.lider=0, como vc fez acima, simplesmente implica que o valor ANTIGO da linha 2 sera 0, o que nao faz sentido para o seu objetivo. qualquer duvida só avisar OBS.: talvez falte um parenteses no IF, mas é só concertar :) Compartilhar este post Link para o post Compartilhar em outros sites
Marcos S. 0 Denunciar post Postado Fevereiro 19, 2014 USE `tms`; DELIMITER $ CREATE DEFINER=`root`@`%` TRIGGER tg_lider_unico_update BEFORE UPDATE ON tms.motorista FOR EACH ROW BEGIN IF (SELECT m.lider FROM tms.motorista m WHERE m.codEmpresa = NEW.codEmpresa AND m.lider = 1) IS NOT NULL AND NEW.lider=1 THEN --aqui sabemos que para aquela empresa existe um lider e que estamos tentando atualizar outro registro para que ele seja o lider,lembre-se que essa trigger é before update UPDATE tms.motorista SET lider=0 WHERE codEmpresa=NEW.codEmpresa; --pronto, nao tem mais ngm como lider na empresa, agora é só deixar que o update prossiga pra que um novo lider seja selecionado END IF; END EDIT: para o insert vc pode usar uma logica semelhante EDIT2: achei massa como vc interpretou o OLD, heheh O OLD e o NEW dentro da trigger se referem ao(aos) registro(s) que vc esta atualizando, vamos supor que vc esteja atualizando o registro 2, o OLD vai pegar o valor antigo da linha e o NEW os novos que vc quer colocar nela. se vc usar SET OLD.lider=0, como vc fez acima, simplesmente implica que o valor ANTIGO da linha 2 sera 0, o que nao faz sentido para o seu objetivo. qualquer duvida só avisar OBS.: talvez falte um parenteses no IF, mas é só concertar :) Agradeço a ajuda! Mas infelizmente não está funcionando :( Quando atualizo a tabela no campo em destaque... Aparece a seguinte mensagem... " ERROR 1442: 1442: Can't update table 'motorista' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. SQL Statement: UPDATE `tms`.`motorista` SET `lider`=1 WHERE `codigo`='2' " Compartilhar este post Link para o post Compartilhar em outros sites
paulojuchem 20 Denunciar post Postado Fevereiro 19, 2014 hmmm, verdade, pro before insert vai funcionar, mas pro update vai entrar em um loop massa, vou pensar um pouco depois posto algo Compartilhar este post Link para o post Compartilhar em outros sites
Marcos S. 0 Denunciar post Postado Fevereiro 20, 2014 hmmm, verdade, pro before insert vai funcionar, mas pro update vai entrar em um loop massa, vou pensar um pouco depois posto algo Olá amigo! Será que este é um caso impossível? Porque mesmo que seja criado Stored Procedure ou Function para fazer UPDATE por fora da Trigger, como tentei de várias maneiras por aqui, o MySql não permite que a Trigger seja criada! E outra...ele também não permite a execução da sintaxe normal de UPDATE no corpo da Trigger, pois ocorre o caso de mutant table, como nosso amigo Motta disse. O que fazer neste caso, Senhores? Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Fevereiro 20, 2014 Faça uma procedure para "limpar" os outros líderes que sejam diferentes do passado pelo parametro. Chame esta procedure após o update. E a solução mais simples que me ocorre. Resolver mutant table não é simples. Eu faria o mais simples , a trigger gera um erro avisando que existe outro (e qual líder) , cabe ao usuário , mudar o atual , incluir ou alterar o novo. O perigo é ficar sem líder, a regra de negócio permite ? Compartilhar este post Link para o post Compartilhar em outros sites
Marcos S. 0 Denunciar post Postado Fevereiro 21, 2014 Faça uma procedure para "limpar" os outros líderes que sejam diferentes do passado pelo parametro. Chame esta procedure após o update. E a solução mais simples que me ocorre. Resolver mutant table não é simples. Eu faria o mais simples , a trigger gera um erro avisando que existe outro (e qual líder) , cabe ao usuário , mudar o atual , incluir ou alterar o novo. O perigo é ficar sem líder, a regra de negócio permite ? Não teve outro jeito, a solução foi feita pela aplicação mesmo. A aplicação limpa o campo de líder antigo da empresa específica e registra o novo líder, sendo que na tabela está sem restrição alguma em relação a esta regra. Obrigado pela ajuda, meus amigos! Foi um grande aprendizado! =D Compartilhar este post Link para o post Compartilhar em outros sites