Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
To tentando fazer com que após eu inserir um novo registro em uma determinada tabela, um campo desta tabela, (que o usuario não vai inserir e sim o banco fará automaticamente) seja atualizado com o mesmo valor que consta na outra tabela.
Trigger:
CREATE OR REPLACE TRIGGER ATUAL_QUANTOTAL_AUT
AFTER INSERT ON SAIDAS
FOR EACH ROW
BEGIN
UPDATE (SELECT S.QUANTTOTAL, P.QUANT
FROM SAIDAS S
INNER JOIN PRODUTOS P ON :NEW.NE = P.NE ) T
SET T.QUANTTOTAL = T.QUANT;
END;
A trigger é criada, é dada como valida, porém quando eu tento fazer um insert simples nessa tabela de saidas, o BD retorna o seguinte erro:
"ORA-06502: PL/SQL: erro: buffer de string de caracteres pequeno demais numérico ou de valor"
Sem a trigger eu consigo inserir normalmente.
Só pra constar os campos q to tentando passar de um para o outro são iguais, de mesmo tamanho.
Alguem saberia me ajudar?
Obrigado
Pois é, eu tinha achado essa especificação de update em algum lugar, vi que é diferente mesmo para fazer isso no oracle.
Porém não consegui executar essa sua solução, ele da erro: "ORA-04079: especificação de gatilho inválida"
Desculpa mas não entendi essa parte do código:
IS
VN_QUANTTOTAL SAIDAS.QUANTTOTAL%TYPE;
VN_QUANT PRODUTOS.quant%type;no update seria:
UPDATE SAIDAS (tabela a ser atualizada) SET QUANTTOTAL = VN_QUANT (valor total q consta na tabela de produtos) WHERE NE (do produto) =:NEW.NE (da tabela de saidas);
já arrumei isso mas tbm não resolveu
VN_QUANTTOTAL SAIDAS.QUANTTOTAL%TYPE;--cria uma variável do mesmo tipo da coluna QUANTTOTAL de SAIDAS
... arrumei isso mas tbm não resolveu ...
Qual a zebra ?
Eu tinha arrumado a tua parte do código pq ali no update, você tava atualizando a quant na tabela de produtos e eu quero atualizar a quant da tabela de saidas (quanttotal), quero que o registro novo q eu inserir puxe o valor que esta na tabela de produtos de um tal produto q foi inserido na tabela de saidas.
Ex:
Tabela produtos | Tabela saidas
NE Produto Quant | NE QUANTTOTAL QUANTUSADA
1 Borracha 2 | 1 2 1
Quero que aquele 2 q esta em quattotal da tabela de saidas vá automaticamente para la assim q for inserida uma nova saida.
Essa quanttotal ali em saidas, é a quantidade total que o produto tinha até ter gerada uma nova saidas desse produto
To tentando criar exatamente assim:
CREATE OR REPLACE TRIGGER ATUAL_QUANTOTAL_AUT
AFTER INSERT ON SAIDAS
FOR EACH ROW
IS
VN_QUANTTOTAL SAIDAS.QUANTTOTAL%TYPE;
VN_QUANT PRODUTOS.quant%type; SELECT S.QUANTTOTAL, P.QUANT,
FROM SAIDAS S
INNER JOIN PRODUTOS P ON :NEW.NE = P.NE;
UPDATE SAIDAS SET QUANTTOTAL = VN_QUANT WHERE NE=:NEW.NE;
END;ORA-04079: especificação de gatilho inválida
Acho que ta dando o erro nessa parte:
IS
VN_QUANTTOTAL SAIDAS.QUANTTOTAL%TYPE;
VN_QUANT PRODUTOS.quant%type;CREATE OR REPLACE TRIGGER ATUAL_QUANTOTAL_AUT
AFTER INSERT ON SAIDAS
FOR EACH ROW
IS
VN_QUANTTOTAL SAIDAS.QUANTTOTAL%TYPE;
VN_QUANT PRODUTOS.quant%type;
BEGIN
SELECT S.QUANTTOTAL, P.QUANT,
INTO VN_QUANTTOTAL , VN_QUANT
FROM SAIDAS S
INNER JOIN PRODUTOS P ON :NEW.NE = P.NE;
UPDATE SAIDAS SET QUANTTOTAL = VN_QUANT WHERE NE=:NEW.NE;
END;Pior é que ta dando erro ainda, mesmo erro de antes.
CREATE OR REPLACE TRIGGER ATUAL_QUANTOTAL_AUT
AFTER INSERT ON SAIDAS
FOR EACH ROW
DECLARE
VN_QUANTTOTAL SAIDAS.QUANTTOTAL%TYPE;
VN_QUANT PRODUTOS.quant%type;
BEGIN
SELECT S.QUANTTOTAL, P.QUANT,
INTO VN_QUANTTOTAL , VN_QUANT
FROM SAIDAS S
INNER JOIN PRODUTOS P ON :NEW.NE = P.NE;
UPDATE SAIDAS SET QUANTTOTAL = VN_QUANT WHERE NE=:NEW.NE;
END;
---
Este SELECT porém só pode retornar uma linha, zero linhas ou mais de uma dará erro na execução.
---
beleza, a trigger foi aceita pelo BD, só que quando eu vou inserir um registro na tabela de saidas pra fazer o teste, ele da o mesmo erro q tava dnado com o update que eu fazia q ta no 1º post. Ele não deixa adicionar o registro dando esse erro:
erro:
"ORA-06502: PL/SQL: erro: buffer de string de caracteres pequeno demais numérico ou de valor"
Na realidade não é update pois é o mesmo registro
CREATE OR REPLACE TRIGGER ATUAL_QUANTOTAL_AUT
AFTER INSERT ON SAIDAS
FOR EACH ROW
DECLARE
VN_QUANTTOTAL SAIDAS.QUANTTOTAL%TYPE;
VN_QUANT PRODUTOS.quant%type;INNER JOIN PRODUTOS P ON :NEW.NE = P.NE;
:NEW.QUANTTOTAL := VN_QUANT;
END;esta trigger ficará mutante, pois está definida sobre a tabela SAIDAS, e faz select nela mesma.
Não no INSERT, creio.
você está certo Motta, fiz um teste aqui. Aprendi mais uma hoje.
Só precisei mudar a trigger para BEFORE INSERT, pois não compilava.
Obrigado, abraços.
Tbm precisei mudar pra BEFORE INSERT pra compilar aqui, só que ta dando o mesmo problema ainda. Na hora que eu vou inserir um registro em "SAIDAS" ele me retorna aquele erro de Buffer de String que tava dando nas outras vezes que eu falei.
Não sei pq não aceitou com AFTER INSERT, seria o mais certo pra mim, pois o campo QUANTTOTAL da minha tabela de saidas não esta definido como obrigatório, portanto a idéia é depois que o usuario registrar que teve uma saida de um produto, ele informar apenas a quantusada e essa trigger se encarregaria por atualizar a QUANTTOTAL automaticamente dessa nova saida no caso, depois que o registro estivesse na tabela.
Se vcs souberem alguma outra solução ou até mesmo fzendo com que essa aceite eu agradeço
Tente rodar a query "por fora" e veja o que ela retorna.
Pra atualizar do jeito que eu quero nao consigo fazer nem rodando em separado.
Testei aqui inserir um registro na tabela de saidas (sem o valor de QUANTTOTAL), sem o trigger como eu disse ele funciona ok, dai depois tentei setar a quanttotal com o valor QUANT do produto da tabela de produtos, mais da erro tbm. Ta dando esse mesmo erro de buffer ai.
Que que será que ta dando?
Rode a query
SELECT S.QUANTTOTAL, P.QUANT
FROM SAIDAS S
INNER JOIN PRODUTOS P ON :NEW.NE = P.NE
Substituindo :NEW.NE pelo valor que seria inserido e veja o resultado.
Essa tua consulta me resultou todos os registros da tabela de saidas com a quant do produto que eu especifiquei o NE
ex:
SELECT S.QUANTTOTAL, P.QUANT
FROM SAIDAS S
INNER JOIN PRODUTOS P ON P.NE = 67298
Eu quero apenas atualizar o dado inserido (que seria esse NE por exemplo), mais que apenas esse NE contenha a quant igual a da tabela de produtos e não todos os registro que é como ta acontecendo.. ai eu fiz assim pra testar:
SELECT S.QUANTTOTAL, P.QUANT
FROM SAIDAS S
INNER JOIN PRODUTOS P ON P.NE = S.NE and S.NE = 67298
beleza deu certo, ate consegui passar isso pra update, atualizei esse registro que queria e tal, ficou assim:
UPDATE (SELECT S.QUANTTOTAL, P.QUANT
FROM SAIDAS S, PRODUTOS P
WHERE S.NE = P.NE AND S.NE=67298 ) T
SET T.QUANTTOTAL = T.QUANT
Funciou perfeitamente se eu adiciono um registro antes e depois rodo essa consulta, ele altera apenas o registro que eu quero com o valor da quant da outra tabela.
O problema é quando eu passo isso pra trigger, a trigger é valida e tudo mais, so que quando eu do insert pra testar ele da o maldito erro de buffer aquele.
A trigger ficou assim:
CREATE OR REPLACE TRIGGER ATUAL_QUANTOTAL_AUT
AFTER INSERT ON SAIDAS
FOR EACH ROW
BEGIN
UPDATE (SELECT S.QUANTTOTAL, P.QUANT
FROM SAIDAS S, PRODUTOS P
WHERE S.NE = P.NE AND S.NE=:NEW.NE ) T
SET T.QUANTTOTAL = T.QUANT;
END;CREATE OR REPLACE TRIGGER ATUAL_QUANTOTAL_AUT
AFTER INSERT ON SAIDAS
FOR EACH ROW
DECLARE
VN_QUANTTOTAL SAIDAS.QUANTTOTAL%TYPE;
VN_QUANT PRODUTOS.QUANT%TYPE; SELECT S.QUANTTOTAL, P.QUANT
INTO VN_QUANTTOTAL , VN_QUANT
FROM SAIDAS S
INNER JOIN PRODUTOS P ON S.NE = P.NE AND S.NE = :NEW.NE;
VN_QUANTTOTAL := VN_QUANT;
END;
Resumindo, "por fora" eu consegui fazer rodar, na trigger não ta funcionando não sei pq
O que você quis dizer com
... Essa tua consulta me resultou todos os registros da tabela de saidas com a quant do produto que eu especifiquei o NE ...
?
A query retorna mais de uma linha ?
Retorna o valor correto ?
tente assim :
CREATE OR REPLACE TRIGGER ATUAL_QUANTOTAL_AUT
BEFORE INSERT ON SAIDAS -- <<<
FOR EACH ROW
DECLARE
VN_QUANTTOTAL SAIDAS.QUANTTOTAL%TYPE;
VN_QUANT PRODUTOS.QUANT%TYPE; SELECT S.QUANTTOTAL, P.QUANT
INTO VN_QUANTTOTAL , VN_QUANT
FROM SAIDAS S
INNER JOIN PRODUTOS P ON S.NE = P.NE AND S.NE = :NEW.NE;
--
:NEW.QUANTTOTAL := VN_QUANT; -- <<<<
END;Eu quis dizer que naquela sua consulta, se eu tenho 3 registros em saidas, ele me retorna os 3 (inclusive o valor que eu quero) e poe o valor total igual ao do NE que eu passei da tabela de produtos.
Na que eu fiz ali em seguida, eu consegui o resultado que eu queria, apenas o registro que de tal NE da tabela de saidas (apenas 1 registro) que é igual ao NE da tabela de produtos, e a quanttotal dele ficou igual ao da outra tabela.
O problema que na trigger nao ta indo.
Essa trigger q você postou agora tbm não funciou, acontece sempre o mesmo problema. A trigger fica valida mais na hora de inserir um registro pra testa da o mesmo problema de sempre
só pra constar.. meu insert ta sendo assim:
INSERT INTO SAIDAS (CODIGO, NE, DATA, QUANTUSA, USUARIO) VALUES (3,67298,'10/02/2010', 20, 'teste');
só não estou passando a coluna QUANTTOTAL, pq justamente essa é para a trigger add o valor.
OBS: Mesmo eu inserindo algo qualquer em QUANTTOTAL ali, esperando que a trigger sobreponha o valor no caso, não funciona
Publique a descrição das tabelas.
Se a quero está retornando apenas uma linha o erro pode estar nas tipos e tamanhos do campo.
Assim vai mostrar o erro é o valor do total obtido.
CREATE OR REPLACE TRIGGER ATUAL_QUANTOTAL_AUT
BEFORE INSERT ON SAIDAS -- <<< FOR EACH ROW
DECLARE
VN_QUANTTOTAL SAIDAS.QUANTTOTAL%TYPE;
VN_QUANT PRODUTOS.QUANT%TYPE; SELECT S.QUANTTOTAL, P.QUANT
INTO VN_QUANTTOTAL , VN_QUANT
FROM SAIDAS S INNER JOIN PRODUTOS P ON S.NE = P.NE AND S.NE = :NEW.NE; --
:NEW.QUANTTOTAL := VN_QUANT; -- <<<<
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20001,'VN_QUANT '||VN_QUANT||' ERRO '||substr(SQLERRM, 1, 200));
END;Quando eu tentei compilar essa tua trigger ele deu erro esse erro:
"ORA-04082: referências NEW ou OLD não permitidas nos gatilhos de nível de tabela"
Dai eu dei uma arrumada pra compilar, compilou e ficou assim:
CREATE OR REPLACE TRIGGER ATUAL_QUANTOTAL_AUT
BEFORE INSERT ON SAIDAS -- <<< FOR EACH ROW
DECLARE
VN_QUANTTOTAL SAIDAS.QUANTTOTAL%TYPE;
VN_QUANT PRODUTOS.QUANT%TYPE; SELECT S.QUANTTOTAL, P.QUANT
INTO VN_QUANTTOTAL , VN_QUANT
FROM SAIDAS S
INNER JOIN PRODUTOS P ON S.NE = P.NE; --
VN_QUANTTOTAL := VN_QUANT; -- <<<<
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20001,'VN_QUANT '||VN_QUANT||' ERRO '||substr(SQLERRM, 1, 200));
END;
Assim a Trigger nao apresento erros, o problema é quando vo da aquele insert pra testa, sempre da o mesmoo erro
Mesmo sabendo que o erro não é de tabela mutante, tentei até criar uma view e trabalhar com ela ao invez da tabela mais não adianta, da o mesmo erro.
Sera que não tem outra maneira de resolver este problema, mas com o mesmo principio, atualizar automaticamente o campo de quantidade total da tabela de saidas com o valor de quantitade total da tabela de produtos, quando uma nova saida for lançada.
grato
A diretiva FOR EACH ROW faz com que a trigger seja executada para cada linha da tabela que sofreu o ins/upd/del , sem ela como está (inibida)
faz a trigger apenas para o comando de ins/upd/del, sendo geral não é permitido o uso das variáveis :NEW e :OLD.
Tópico antigo, mas vamos a resolução, quando você usar o AFTER ou tentar fazer um UPDATE na própria tabela que se está usando a trigger acontece o problema apresentado. Para resolver esse problema você deve usar o BEFORE, pois assim você pode alterar algum campo da tabela. O motivo acontece, pois o banco está realizando um transação na tabela referida e você no momento não fazer outra transação em cima da mesma.
No caso, eu faria usando um cursor, varrendo e atualizando os dados que sejam necessários.
>
To tentando fazer com que após eu inserir um novo registro em uma determinada tabela, um campo desta tabela, (que o usuario não vai inserir e sim o banco fará automaticamente) seja atualizado com o mesmo valor que consta na outra tabela.
Trigger:
CREATE OR REPLACE TRIGGER ATUAL_QUANTOTAL_AUT
AFTER INSERT ON SAIDAS
FOR EACH ROW
BEGIN
UPDATE (SELECT S.QUANTTOTAL, P.QUANT
FROM SAIDAS S
INNER JOIN PRODUTOS P ON :NEW.NE = P.NE ) T
SET T.QUANTTOTAL = T.QUANT;
END;
A trigger é criada, é dada como valida, porém quando eu tento fazer um insert simples nessa tabela de saidas, o BD retorna o seguinte erro:
"ORA-06502: PL/SQL: erro: buffer de string de caracteres pequeno demais numérico ou de valor"
Sem a trigger eu consigo inserir normalmente.
Só pra constar os campos q to tentando passar de um para o outro são iguais, de mesmo tamanho.
Alguem saberia me ajudar?
Obrigado
Que sintaxe é esta ?
UPDATE (SELECT S.QUANTTOTAL, P.QUANT
FROM SAIDAS S
INNER JOIN PRODUTOS P ON :NEW.NE = P.NE ) T
SET T.QUANTTOTAL = T.QUANT;
Que tabela se quer atualizar ?
Não se faz update cruzado no Oracle.
Uma solução:
CREATE OR REPLACE TRIGGER ATUAL_QUANTOTAL_AUT
AFTER INSERT ON SAIDAS
FOR EACH ROW
IS
BEGIN