Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) Varios inserts ou nada


BetoGroo

Pergunta

10 respostass a esta questão

Posts Recomendados

  • 0
Olá!

Gostaria de saber se tem uma maneira de eu executar vários inserts, porém, para ser concuído, TODOS tem que ser executados. Se UM der problema, nenhum será executado!

Eu pensei em uma Stored Procedure. Será que resolveria meu problema???

Em seu código de programa, se suas tabelas forem InnoDB (MyISAM não obedece), você pode enviar o comando de START TRANSACTION e, no final, enviar o comando de COMMIT se tudo foi OK ou ROLLBACK se algo deu errado. Estes comandos podem ser executados em uma Storage procedure, também.

Link para o comentário
Compartilhar em outros sites

  • 0
Só uma dúvida:

Uma TRIGGER reconhece um INSERT oriundo de uma PROCEDURE?

Um trigger é um procedimento "embutido" em uma tabela, se é que posso definir assim.

Este procedimento é disparado, a cada vez que a tabela sofre uma modificação (insert, update ou delete) conforme o tipo de trigger. O disparo pode ser antes que a modificação seja processada ou após.

Sendo assim, respondendo sua pergunta, sim. um trigger reconhece um insert oriundo de uma procedure

Link para o comentário
Compartilhar em outros sites

  • 0

Então vamos lá:

Tenho a procedure:

CREATE PROCEDURE `delpol`.`ADD_func2`   (
    IN rlIdDele INTEGER, IN rlIdCargo INTEGER, IN nomeFunc VARCHAR(50), IN nasctoFunc DATE, #tb funcionario
    IN numeroTel VARCHAR(9), IN dddTel CHAR(2) #tb telefone
                                        )
    
BEGIN
            INSERT INTO funcionario (rl_id_dele, rl_id_cargo, nome_func, nascto_func)
            VALUES(rlIdDele, rlIdCargo, nomeFunc, nasctoFunc);
            
            SELECT DISTINCT LAST_INSERT_ID() INTO @rlIdFunc FROM funcionario;
            
            INSERT INTO telefone (rl_id_func, rl_id_tipo_tel, numero_tel, ddd_tel)
            VALUES (@rlIdFunc, 1, numeroTel, dddTel);
               
  
END//
e a TRIGGER:
DELIMITER //

CREATE TRIGGER `delpol`.`TR_INCREMENTA_id_tel` BEFORE INSERT ON `delpol`.`telefone`
 FOR EACH ROW BEGIN
DECLARE num INTEGER;
SET num = (SELECT MAX(id_tel) FROM telefone WHERE rl_id_func = NEW.rl_id_func);
IF (num <= 0) OR (num IS NULL) THEN
SET num = 1;
ELSE
SET num = num + 1;
END IF;
SET NEW.id_tel = num;
END
//
Quando chamo a procedure:
CALL ADD_func2 (1,1,'BETOGROO','1979-05-13','9999-2222','16')
Da o seguinte erro: #1364 - Field 'id_tel' doesn't have a default value Porém, se eu executar a query abaixo:
INSERT INTO funcionario (rl_id_dele, rl_id_cargo, nome_func, nascto_func)
VALUES(1, 1, 'BETOGROO', '1979-05-13');
SELECT DISTINCT LAST_INSERT_ID() INTO @rlIdFunc FROM funcionario;
INSERT INTO telefone (rl_id_func, rl_id_tipo_tel, numero_tel, ddd_tel)
VALUES (@rlIdFunc, 1, '9999-2222', '16');

Não dá erro algum, e insere os dados normalmente nas tabelas!

O que está acontecendo???

Obs: Estas são as tabelas:

banco.png

Link para o comentário
Compartilhar em outros sites

  • 0

Tá "na mão":

CREATE  TABLE IF NOT EXISTS `delpol`.`telefone` (
  `id_tel` INT UNSIGNED NOT NULL ,
  `rl_id_func` INT UNSIGNED NOT NULL ,
  `rl_id_tipo_tel` INT UNSIGNED NOT NULL ,
  `numero_tel` CHAR(9) NOT NULL ,
  `ddd_tel` CHAR(2) NOT NULL ,
  PRIMARY KEY (`id_tel`, `rl_id_func`) ,
  INDEX telefone_FKIndex1 (`rl_id_tipo_tel` ASC) ,
  INDEX telefone_FKIndex2 (`rl_id_func` ASC) ,
  CONSTRAINT `tel_tipo_tel`
    FOREIGN KEY (`rl_id_tipo_tel` )
    REFERENCES `delpol`.`tipo_telefone` (`id_tipo_tel` ),
  CONSTRAINT `func_tele`
    FOREIGN KEY (`rl_id_func` )
    REFERENCES `delpol`.`funcionario` (`id_func` ))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_bin
PACK_KEYS = 0
ROW_FORMAT = DEFAULT

Link para o comentário
Compartilhar em outros sites

  • 0

Oi, 'BetoGroo'!

Modifique sua tabela assim:

ALTER TABLE `delpol`.`telefone`
  MODIFY `id_tel` INT UNSIGNED NOT NULL DEFAULT 0,
  DROP INDEX telefone_FKIndex1,
  DROP INDEX telefone_FKIndex2;
Os índices estão duplicados e causarão deficiência na performance desta tabela quando ela estiver carregada. Modifique o trigger para que fique assim:
DELIMITER //

CREATE TRIGGER `delpol`.`TR_INCREMENTA_id_tel` BEFORE INSERT ON `delpol`.`telefone`
FOR EACH ROW BEGIN
DECLARE num INTEGER;
/* a função COALESCE retorna o primeiro elemento não nulo */
   SET num = SELECT COALESCE((SELECT MAX(id_tel) FROM telefone WHERE rl_id_func = NEW.rl_id_func), 0);
/* Não há a necessidade de testar o nulo pois a função coalesce já resolveu isto. E não há a necessidade de testar valor menor que zero pois o atributo id_tem é unsigned, ou seja, pertence ao conjunto dos números naturais */
   IF (num = 0) THEN
      SET num = 1;
   ELSE
      SET num = num + 1;
   END IF;
   SET NEW.id_tel = num;
END
//

Teste e informe, por favor.

Link para o comentário
Compartilhar em outros sites

  • 0

Muito obrigado Denis.

Estes índices foram criados pelo MySQL Worchbench. Eu preciso estudar um pouco mais sobre índices.

Apesar que, mesmo sem deletá-los deu certo. Eu apenas setei o valor default = 0 no atributo id_tem e a TRIGGER foi disparada!

É necessário mesmo deletá-los??

Link para o comentário
Compartilhar em outros sites

  • 0
Muito obrigado Denis.

Estes índices foram criados pelo MySQL Worchbench. Eu preciso estudar um pouco mais sobre índices.

Apesar que, mesmo sem deletá-los deu certo. Eu apenas setei o valor default = 0 no atributo id_tem e a TRIGGER foi disparada!

É necessário mesmo deletá-los??

Sim. Eles já existem na forma de foreign key. No momento você não sentirá deficiência na performance, mas quando a tabela tiver cheia, cada atualização terá o tempo aumentado porque terá que atualizar estes índices, além dos índices de foreign key.

Assunto encerrado?

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novos posts.


  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...