View Full Version : MySQL + NetBeans - TRIGGERS


lilcrazy
27-01-2008, 02:35
Boas pessoal,

Será que alguém poderia dar uma ajudita aqui neste problema. Estou a desenvolver uma pequena aplicação de Base de Dados e interligá-la com o NetBeans. As tabelas foram criadas no MySQL, a ligação é feita com sucesso a partir do NetBeans à Base de Dados, a maior parte da aplicação já se encontra implementada. O problema que ando a tentar resolver há algumas horas é o seguinte:

CREATE OR REPLACE TRIGGER actualiza_stock
BEFORE
UPDATE OF quantidade ON PRODUTOS
FOR EACH ROW
BEGIN
UPDATE PRODUTOS SET quantidade = :old.quantidade + :new.quantidade
WHERE id_produto = :old.id_produto;
END;
/

Este trigger, o que faz é actualizar o stock de determinado produto. Ou seja, na interface encontram-se campos de texto relativos a algumas coluna da tabela PRODUTOS, um deles é relacionado com a quantidade de um produto a inserir na base de dados. Ao fazer Update, o objectivo é colocar no campo de texto 'quantidade' o número novo de produtos e adicionar esse número à quantidade de produtos existentes. Exempo: Existiam 30 Produtos, na interface colocamos 10 no campo de texto respectivo, e na base de dados, o Produto ia ficar com 40 unidades.
O trigger é aceite pelo MySQL, mas ao fazer UPDATE no código em JAVA dá o seguinte erro:

java.sql.SQLException: [Oracle][ODBC][Ora]ORA-04091: tabela EMPRESA.PRODUTOS está em mutação, trigger não a pode ler ou modificar
ORA-06512: na "EMPRESA.ACTUALIZA_STOCK", linha 2
ORA-04088: erro durante a execução do trigger 'EMPRESA.ACTUALIZA_STOCK'
at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc .java:6957)
at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java :7114)
at sun.jdbc.odbc.JdbcOdbc.SQLExecDirect(JdbcOdbc.java :3110)
at sun.jdbc.odbc.JdbcOdbcStatement.execute(JdbcOdbcSt atement.java:338)
at sun.jdbc.odbc.JdbcOdbcStatement.executeQuery(JdbcO dbcStatement.java:253)

(por aí fora...)


Alguém me consegue ajudar nisto?

Obrigado pessoal. Bom resto de fim de semana.

spastikman
27-01-2008, 02:43
não tenho a certeza, mas se for como em oracle, não podes alterar directamente valores de uma tabela sobre a qual está a incidir uma query.

Por outras palavras, se tens uma query a fazer update à tabela X não a podes alterar com o trigger directamente. Tens de usar tabelas temporárias.

Triggers funcionam sem espinhas quando tens uma query na tabela A e o trigger executa algo na tabela B.

AliFromCairo
27-01-2008, 03:13
Bom, antes de mais isso é Oracle e não MySQL. De qualquer forma, o que estás a tentar fazer pode ser feito sem recurso a um trigger. Se tens um campo X com um determinado valor, e pretendes incrementar o valor do campo X em Y unidades (valor introduzido na texbox), um simples update faz-te isso:


UPDATE produtos SET quantidade = quantidade + Y
WHERE id_produto = 20


Se quiseres manter o trigger (!), podes utilizar uma tabela temporária como o spastikman referiu mas, para além disso, vais precisar de criar ainda mais triggers para resolver o problema. Podes pesquisar no google por "oracle mutable tables" que vais certamente encontrar soluções, mas considera esse problema como um aviso por parte do SGBD de que algo não está a ser feito como devia :P.

lilcrazy
27-01-2008, 16:04
Pessoal, antes de mais as minhas desculpas, de facto era Oracle e não MySQL. Confundi porque estava a testar no SQLPlus (daí a minha troca de palavras), e já eram 5h da matina :P

Obrigado pela ajuda pessoal. De qualquer das maneiras eu depois consegui perceber o que estava a suceder, só que resolver o problema...

O objectivo era usar um ou dois triggers na aplicação. Posso fazer a tal adição no UPDATE, isto caso não consiga com o trigger.

Obrigado mais uma vez.

Um bom resto de fim de semana.

AliFromCairo
27-01-2008, 16:50
Podes criar triggers na mesma. Por exemplo, para garantir que a quantidade tem sempre um valor positivo ou que não pode ultrapassar um determinado valor (stock limitado :007:). Claro que em Oracle existem outros mecanismos para garantir estas restrições, mas de qualquer maneira, penso que fazem bastante mais sentido do que aquilo que pretentes fazer com o teu trigger.

lilcrazy
27-01-2008, 19:24
Já consegui colocar 2 triggers a funcionar, isto para tabelas diferentes por causa do tal erro de mutação de tabelas.

A função e o procedimento que criei também já funcionam :)

Quanto à dúvida inicial, fazia mais sentido utilizar isto: "UPDATE TABELA SET quantidade = quantidade + x";

Agora tenho um problema num procedimento. Já agora se for possível tirar a dúvida por aqui...

Criei no SQLPlus um procedimento e ele é bem implementado e funciona correctamente. No entanto se correr "EXECUTE procedimento(param1, param2)"; no NetBeans em Java, aparece o seguinte erro:

java.sql.SQLException: [Oracle][ODBC]Syntax error or access violation.
at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc .java:6957)
at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java :7114)
at sun.jdbc.odbc.JdbcOdbc.SQLExecDirect(JdbcOdbc.java :3110)
at sun.jdbc.odbc.JdbcOdbcStatement.execute(JdbcOdbcSt atement.java:338)
at sun.jdbc.odbc.JdbcOdbcStatement.executeQuery(JdbcO dbcStatement.java:253)

Obrigado pessoal pela ajuda ;-)

AliFromCairo
27-01-2008, 19:44
Verifica se o teu stored procedure está contido em algum package e se o user que estás a utilizar tem permissões de acesso a esse mesmo package.

lilcrazy
27-01-2008, 23:31
Eu tenho permissão para procedimentos. Vou tentar colocar esse procedimento numa package e ver no que dá..

Obrigado.

Fiz uma package, mas continua a dar o mesmo erro. :/