Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Marisa Lima

Trigger em mysql

Recommended Posts

Vazias como? Pode ser isso sim.

 

Notei que você tem um WHERE activo='0', certifique-se de que todos os registros que está selecionando se encaixam nesse filtro também.

 

Uma dica para melhor legibilidade do código, não nomeie variáveis com os nomes do campos, por exemplo se você que uma variável pra guardar o id_colaborador, nomeie-a como varIdColaborador. Fica melhor de você diferenciar o que é variável e o que é campo e quem sabe encontrar algum possível problema.

 

Por enquanto foi o que eu notei no código acima, se não encontrar o problema com essas dicas terá que debugar mais a fundo, ou eu tento replicar tua base aqui e tentar encontrar o problema.

 

Abraço e boa sorte.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vou alterar as variaveis. Neste momento ainda não tenho a informação toda na bd como eu pensava, só ao fazer os testes é que detectei que ainda faltam inserir dados, assim que estiver tudo inserido vou voltar a testar e ver se ainda dá erro.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Estive a testar com poucos dados e funciona, mas tem alturas em que duplica registos, insere duas vezes a mesma coisa. Não percebo porque faz isso. Como é que eu posso enviar o dump da base de dados para você poder testar e detectar onde estou a errar?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia,

 

Pode me enviar por e-mail, te passei uma mensagem com ele ;] Aí me informa o nome da Procedure que preciso testar.

 

Ficarei no aguardo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia Marisa,

 

Perdão pela demora só agora pude verificar o caso.

 

Bom, importei aqui a sua base e li o e-mail, que estava bem claro. O problema é que está inserindo duas vezes cada colaborador correto? E isto é feito pela Trigger abaixo:

 

DROP TRIGGER IF EXISTS `Insert_momento_avaliacao_colaborador`;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='';
DELIMITER //
CREATE TRIGGER `Insert_momento_avaliacao_colaborador` AFTER INSERT ON `momento_avaliacao` FOR EACH ROW BEGIN
   DECLARE varIdcolaborador int default 0;

   DECLARE f int DEFAULT 0;
   DECLARE cursorExemplo CURSOR FOR SELECT colaborador.id FROM colaborador, dados_colaborador WHERE activo = 0 AND dados_colaborador.id_chefe > 0;
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET f = 1;

   OPEN cursorExemplo ;
   REPEAT
       FETCH cursorExemplo INTO varIdcolaborador ;

       INSERT INTO momento_avaliacao_colaborador (id_colaborador,id_momento_avaliacao,status) VALUES (varIdcolaborador,NEW.id,1);
   UNTIL (f = 1) END REPEAT ;

   CLOSE cursorExemplo ;
END//
DELIMITER ;

Correto?

 

Bom, acredito que seja o SELECT do CURSOR que esteja retornando duplicado, pode ser algo entre a relação das duas tabelas que ele usa. Como você não exportou os dados não pude simular :/ Você chegou a executar aquele SELECT pra verificar o retorno dele? Acho que se na tabela dados_colaborador tiver + de 1 registro pra cada colaborador, vai retornar o mesmo N vezes.

 

Se quiser exportar alguns colaboradores e os outros dados que são necessários pra simulação (tabelas relacionadas) e me passar, fique a vontade. Senão verifique esta condição que citei do SELECT.

 

Se eu entendi bem a função do mesmo, ele deve retornar colaboradores com o campo colaborador.activo como um quesito de filtro, e o campo id_chefe da tabela relacionada dados_colaborador como outro quesito. Acho que o teu SELECT ali que está retornando duplicado (Se for o caso) pode ser substituído por isso e atenderá a mesma lógica, sem duplicar o retorno:

 

SELECT c.id FROM colaborador c 
WHERE c.activo = 0 
AND EXISTS (
   SELECT 1 FROM dados_colaborador dc 
   WHERE dc.id_colaborador = c.id_colaborador 
   AND   dc.id_chefe > 0
)

É um palpite. Faça uns testes, execute estes SELECTs, faça ajustes se necessário. Qualquer coisa estamos aí também =]

 

Abraço e boa sorte, fico a disposição.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia.

 

Não enviei os dados por causa da confidencialidade. Isto é um projecto de estágio e tenho o compromisso de guardar a confidecialidade dos dados que me são fornecidos. Vou testar assim que poder e depois digo algo. Obrigada!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia.

 

Não enviei os dados por causa da confidencialidade. Isto é um projecto de estágio e tenho o compromisso de guardar a confidecialidade dos dados que me são fornecidos. Vou testar assim que poder e depois digo algo. Obrigada!

Tranquilo, compreendo a situação =]

 

Bons testes, ficarei no aguardo. Valeu.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia. Fiz as alterações que me indicas-te, mas continua na mesma a inserir o colaborador duas vezes. Testei apenas com um colaborador. Já não sei mais o que fazer e tenho de ter o projecto pronto quinta-feira. Se houver mais alguma dica que me possas dar? Obrigada

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia Marisa.

 

Bah... O SELECT retorna apenas uma vez? Se não é ele então o problema tá acontecendo em outra Trigger.

 

Faça o seguinte, crie uma tabela de log, com uma coluna id, uma coluna tabela, e uma coluna trigger (ou procedure), e uma coluna id_colaborador, não precisa estar relacionada nem nada. Em cada Trigger tua coloque um INSERT INTO log (tabela, trigger, id_colaborador) VALUES ('nome da tabela em que você está inserindo algo','nome da trigger / procedure que está fazendo essa inserção','id do colaborador que está sendo inserido'). Não se esqueça que você deve colocar dentro dos loopings, para que seja inserido 1 log pra cada registro nas outras.

 

Assim você poderá ver como está sendo inserido as coisas, em que momento, e verificar o que deveria inserir e o que não deveria. A partir desse ponto basta debugar o SELECT ou dados da Procedure / Trigger com problema.

 

Qualquer coisa estamos aí. Se você quiser podia passar um colaborador fictício para que eu simule.

 

Boa sorte e abraço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Enviei o script da bd com alguns dados para o seu email. Obrigada.

 

Enviei uma script da bd com dados para o seu email, testei o select e retorna apenas uma linha é claro que só tem um colaborador para mostrar, se tiver mais retorna todos!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Enviei o script da bd com alguns dados para o seu email. Obrigada.

 

Enviei uma script da bd com dados para o seu email, testei o select e retorna apenas uma linha é claro que só tem um colaborador para mostrar, se tiver mais retorna todos!

Ok, vou verificar e te dou um retorno ainda hoje.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa noite Marisa,

 

Bom, verifiquei bastante aqui. O SELECT do CURSOR estava retornando uma linha com ID e uma linha nula, eu substitui ele por este:

 

SELECT c.id FROM colaborador c 
JOIN dados_colaborador dc ON dc.id_colaborador = c.id
WHERE c.activo = 0 
AND   dc.id_chefe > 0 AND dc.data_fim = 0000-00-00

Ainda assim, a Trigger continuava executando 2 vezes o laço. Ela em si é chamada apenas uma vez mesmo, mas o laço era executado duas vezes, é como se o CURSOR estivesse se perdendo. Ainda não resolvi o problema, queria checar contigo por que tu precisa selecionar todos os colaboradores nesse SELECT ? Se você está inserindo registro relacionado com apenas 1 colaborador, porque selecionar todos?

 

Pois eu retirei o laço, deixei pra inserir apenas 1 colaborador retornado do SELECT e isso funcionou.

 

Assim:

 

DROP TRIGGER IF EXISTS `Insert_momento_avaliacao_colaborador`;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='';
DELIMITER $$
CREATE TRIGGER `Insert_momento_avaliacao_colaborador` AFTER INSERT ON `momento_avaliacao` FOR EACH ROW BEGIN
   DECLARE varIdcolaborador int;

--    DECLARE f int DEFAULT 0;

--    DECLARE cursorExemplo CURSOR FOR (SELECT DISTINCT c.id FROM colaborador c JOIN dados_colaborador dc ON dc.id_colaborador = c.id WHERE c.activo = 0 AND   dc.id_chefe > 0 AND dc.data_fim = 0000-00-00);

SET varIdcolaborador = (
	SELECT c.id FROM colaborador c 
	JOIN dados_colaborador dc ON dc.id_colaborador = c.id 
	WHERE c.activo = 0 AND dc.id_chefe > 0 AND dc.data_fim = 0000-00-00
);

   -- DECLARE CONTINUE HANDLER FOR NOT FOUND SET f = 1;

   -- OPEN cursorExemplo ;

   -- WHILE (f <> 1) DO
       -- FETCH cursorExemplo INTO varIdcolaborador ;

INSERT INTO momento_avaliacao_colaborador (id_colaborador,id_momento_avaliacao) VALUES (varIdcolaborador,NEW.id);
   --END WHILE ;

   -- CLOSE cursorExemplo ;

END $$

Ainda assim continuarei tentando pra resolver seu caso, fico no aguardo da resposta.

 

--------------------------

 

Consegui eu acho!

 

Depois que eu mudei aquele SELECT que falei acima já devia ter funcionado, porém eu tinha mudado de REPEAT para WHILE pra fazer um teste e não voltei. Agora recoloquei o REPEAT com o SELECT mudado e está inserindo apenas uma vez. Segue a minha Trigger mudada:

 

DROP TRIGGER IF EXISTS `Insert_momento_avaliacao_colaborador`;

DELIMITER $$

CREATE TRIGGER `Insert_momento_avaliacao_colaborador` AFTER INSERT ON `momento_avaliacao` FOR EACH ROW BEGIN
   DECLARE varIdcolaborador int;
   DECLARE f int DEFAULT 5;
   DECLARE cursorTeste CURSOR FOR 
       (
           SELECT DISTINCT c.id FROM colaborador c 
           JOIN dados_colaborador dc ON dc.id_colaborador = c.id 
           WHERE c.activo = 0 AND dc.id_chefe > 0 AND dc.data_fim = 0000-00-00
       );

   DECLARE CONTINUE HANDLER FOR NOT FOUND SET f = 10;

   OPEN cursorTeste ;

   REPEAT
       FETCH cursorTeste INTO varIdcolaborador ;

       INSERT INTO momento_avaliacao_colaborador (id_colaborador,id_momento_avaliacao) VALUES (varIdcolaborador,NEW.id);
   UNTIL (f <> 10) END REPEAT ;

   CLOSE cursorTeste ;

END $$

DELIMITER ;

Eu troquei também os valores de f, apenas para efeito de testes, e acabou funcionando.

 

Veja se funciona para você, e adapte a lógica para as outras PROCEDUREs que estão duplicando.

 

Se precisar de ajuda estamos aí, abraço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia!

 

Fiz as alterações que me indicas-te e nos colaboradores só insere apenas uma vez cada um deles, mas nas procedures insere correctamente todos os dados mas repete um deles. Por exemplo tenho 7 linhas para inserir, insere mas na ultima insere duas vezes. Tentei fazer as mesmas alterações que fiz na trigger e não funciona, "crachando" o mysql ao executar e tenho de voltar a instalar a aplicação!

Será que pode ver o que se passa?

Procedure

 

CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_competencia_departamental_avaliacao`(IN `varId_colaborador` INT, IN `varId_momento_avaliacao_colaborador` INT)

LANGUAGE SQL

NOT DETERMINISTIC

CONTAINS SQL

SQL SECURITY DEFINER

COMMENT ''

BEGIN

DECLARE varIddepart int;

DECLARE f int DEFAULT 5;

DECLARE cursorExemplo CURSOR FOR

(

SELECT id_competencia_departamental cdc

FROM competencia_departamental_colaborador cdc JOIN competencia_departamental cd ON

cdc.id_competencia_departamental=cd.id

WHERE cdc.activo=0

AND cdc.id_colaborador=varId_colaborador

AND cd.activo=0

);

DECLARE CONTINUE HANDLER FOR NOT FOUND SET f = 10;

 

OPEN cursorExemplo ;

 

REPEAT

FETCH cursorExemplo INTO varIddepart ;

 

 

INSERT INTO avaliacao_competencia_departamental_momento(id_momento_avaliacao_colaborador,id_competencia_departamental) VALUES (varId_momento_avaliacao_colaborador,varIddepart);

UNTIL (f <> 10) END REPEAT ;

 

CLOSE cursorExemplo ;

 

 

END

 

Se a colocar desta forma bloqueia o mysql!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia Marisa,

 

Assim que possível vou verificar e te dou um retorno.

 

Marisa, acho que ele pode estar entrando em looping.

 

Tente mexer nos valores de f que controlam o laço, verificar o teu SELECT, fazer testes assim ou até criar uma tabela de log pra que ele registre a quantidade de inserções que está fazendo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.