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

Problema Em Manter Estoque


Guest --Giuliano --

Pergunta

Guest --Giuliano --

Olá pessoal!

Estou desenvolvendo uma aplicação em que se tem que manter um estoque. Então, ao se realizar um cadastro de compra de soja por exemplo, eu vou e adiciono a quantidade no estoque. Mas isso está sendo feito em instruções SQL separadas e independentes, onde adiciono a compra de soja, e depois atualizo o estoque. Mas dessa forma tem pequena chance, mas tem, de gerar uma inconsistência, no caso de acontecer algum problema com a primeira instrução e executar a segunda. Por exemplo, se acabar a energia quando tiver executando a segunda?! Como resolver esse problema?

Tem como realizar um insert e um update na mesma instrução? Pois dessa maneira, de acordo com a propriedade ACID, resolveria o problema, ou realizaria tudo ou nada... Qual sugestão para esse problema? Obrigado!

Link para o comentário
Compartilhar em outros sites

4 respostass a esta questão

Posts Recomendados

  • 0
Olá pessoal!

Estou desenvolvendo uma aplicação em que se tem que manter um estoque. Então, ao se realizar um cadastro de compra de soja por exemplo, eu vou e adiciono a quantidade no estoque. Mas isso está sendo feito em instruções SQL separadas e independentes, onde adiciono a compra de soja, e depois atualizo o estoque. Mas dessa forma tem pequena chance, mas tem, de gerar uma inconsistência, no caso de acontecer algum problema com a primeira instrução e executar a segunda. Por exemplo, se acabar a energia quando tiver executando a segunda?! Como resolver esse problema?

Tem como realizar um insert e um update na mesma instrução? Pois dessa maneira, de acordo com a propriedade ACID, resolveria o problema, ou realizaria tudo ou nada... Qual sugestão para esse problema? Obrigado!

Oi, Giuliano!

Utilize uma trigger parecida com esta que uso para trilha de auditoria:

DELIMITER $$;

DROP TRIGGER `meubancodedados`.`trUPDLogCartaoDeCredito`$$

create trigger `trUPDLogCartaoDeCredito` BEFORE UPDATE on `cartaodecredito` 
for each row BEGIN
   insert into trilha_audit.cartaodecredito (Acao, CartaoID, NM_Cartao, Taxa, VL_Minimo, Incluido_EM,
    Incluido_POR, Alterado_EM, Alterado_POR) 
   values ('A', OLD.CartaoID, OLD.NM_Cartao, OLD.Taxa, OLD.VL_Minimo, OLD.Incluido_EM,
    OLD.Incluido_POR, OLD.Alterado_EM, OLD.Alterado_POR);
END;
$$

DROP TRIGGER `meubancodedados`.`trDELLogCartaoDeCredito`$$

create trigger `trDELLogCartaoDeCredito` BEFORE DELETE on `cartaodecredito` 
for each row BEGIN
   insert into trilha_audit.cartaodecredito (Acao, CartaoID, NM_Cartao, Taxa, VL_Minimo, Incluido_EM,
    Incluido_POR, Alterado_EM, Alterado_POR) 
   values ('D', OLD.CartaoID, OLD.NM_Cartao, OLD.Taxa, OLD.VL_Minimo, OLD.Incluido_EM,
    OLD.Incluido_POR, OLD.Alterado_EM, OLD.Alterado_POR);
END;
$$

DELIMITER;$$

Estas instruções ocorrem momento antes de atualizar o banco principal "meubancodedados". O banco "trilha_audit" possui as mesmas tabelas (com as mesmas estruturas) do banco original (não todas. Somente as que necessito auditar).

Como a operação é em bases transacionais, tipo innodb, e dentro de uma transação, então se não gravar no banco original, esta é desfeita, também.

Isto não vale para quem usa base não transacional, como myisam, por exemplo.

No seu caso, substitua BEFORE UPDATE por BEFORE INSERT

Para saber mais sobre triggers leia http://dev.mysql.com/doc/refman/5.1/en/triggers.html.

att

Denis Courcy

Editado por Denis Courcy
Link para o comentário
Compartilhar em outros sites

  • 0
Guest --Giuliano --

Olá Amigo!

Grande Dica, obrigado! Fiz uns estudos sobre o assunto e consegui implementar, e resolve o meu problema. O que não consegui achar é como obtenho o código de criação de uma trigger, tipo o SHOW CREATE TABLE, pois posso precisar ver o código para alterá-lo, tem como fazer isso?. Para alterar, me parece que é só substiruir o CREATE por ALTER, tipo ALTER TRIGGER nome_trigger ...

Vlw! Obrigado!

Att. Giuliano

Link para o comentário
Compartilhar em outros sites

  • 0
Guest --Giuliano --

Amigo,

Eu pesquisei pra caramba e não consegui fazer um simples IF. Utilizei os operadores de controle de fluxo, mas não consegui.

Código:

DELIMITER |

CREATE TRIGGER atualiza_est_acoes AFTER UPDATE ON compra_acoes

FOR EACH ROW BEGIN

if(old.empresa != new.empresa or old.quaAco != new.quaAco){

UPDATE estoque_acoes set quantidade = quantidade - old.quaAco where empresa = old.empresa;

UPDATE estoque_acoes set quantidade = quantidade + new.quaAco where empresa = new.empresa;

}

END;

|

DELIMITER;

O IF está na sintaxe tradicional, só pra entender... Eu tenho uma tabela de compra de acoes, e outra de estoque de acoes.

Eu simplismente só quero atualizar o estoque se a empresa ou a quantidade de acoes do registro da compra de acoes foram alterados, pois se eles não foram alterados não preciso atualizar o estoque...

Eu não achei a sintaxe do if no mysql, mas vi um artigo que tem uma funcao que usa essa sintaxe tradicional. Como fazer esse if?

Obrigado!

Link para o comentário
Compartilhar em outros sites

  • 0
Amigo,

Eu pesquisei pra caramba e não consegui fazer um simples IF. Utilizei os operadores de controle de fluxo, mas não consegui.

...

Eu não achei a sintaxe do if no mysql, mas vi um artigo que tem uma funcao que usa essa sintaxe tradicional. Como fazer esse if?

Oi, Giuliano!

A referência a controles de fluxos está, no manual da versão 4.1x, no capítulo 11.1.9 - Flow Control Constructs; na versão 5.0x, está no catítulo 17.2.10. Abaixo coloco a sintaxe correta.

Outra coisa, Suponho que "quaAco" e "empresa" sejam atributos(campos) da tabela "compra_acoes". Pois se não forem, então a lógica está errada, também.

Código:

DELIMITER |
    CREATE TRIGGER atualiza_est_acoes AFTER UPDATE ON compra_acoes
    FOR EACH ROW BEGIN
       IF old.empresa <> new.empresa or old.quaAco <> new.quaAco THEN
          UPDATE estoque_acoes set quantidade = quantidade - old.quaAco  
          WHERE empresa = old.empresa;
          UPDATE estoque_acoes set quantidade = quantidade + new.quaAco 
          WHERE empresa = new.empresa;
       END IF;           
   END;
|
DELIMITER;

Nota: Procure, neste forum, o tópico "Busca Por Fonemas" de minha autoria e veja a sintaxe de diversos "operadores de controle de fluxo".

Att

Denis Courcy

Editado por Denis Courcy
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,1k
    • Posts
      651,8k
×
×
  • Criar Novo...