Alguma coisa tem de errado neste código eu suspeito que seja esta trigger no bloco For Select ... Into Do, se eu retirar este bloco funciona mas logicamente somente se houver um item por pedido, quando eu adiciono este bloco For Select ... Into Do o erro acontece...
Invalid insert or update value(s): object columns are
constrained - no 2 table rows can have duplicate column values.
violation of PRIMARY or UNIQUE KEY constraint "PK_SALDOESTOQUE" on table "SALDO_ESTOQUE".
Problematic key value is ("ID_MOVIMENTO" = 62, "ID_PRODUTO" = 1, "ID_EMBALAGEM" = 1).
At procedure 'ADD_SALDO_ESTOQUE' line: 15, col: 4
At procedure 'REAJUSTAR_SALDOESTQ' line: 41, col: 8
At trigger 'ADICIONAR_ESTOQUE' line: 34, col: 11.
alguém poderia me dar um Help?
Explicação do código:
Existe as tabelas de pedido_entrada, item_entrada, movimento_estoque e saldo_estoque.
pedido_entrada e item_entrada: armazena os pedidos de compra.
movimento_estoque e saldo_estoque: armazena as movimentações e seu saldo de estoque, respectivamente.
Esta Trigger é disparado depois de atualizar a tabela pedido_entrada (pedido de compra) aonde o campo status for alterado de (P)endente para (F)inalizado.
A inteção é adicionar todos os itens do pedido de compra na tabela saldo de estoque (não esquecendo que a estrutura é um mestre-detalhe movimento_estoque 1-N saldo_estoque).
set term ^ ;
create trigger adicionar_estoque for pedido_entrada
active after update position 0
as
declare variable idMovimento integer;
declare variable idProduto integer;
declare variable idEmbalagem integer;
declare variable valorCusto numeric(13,2);
declare variable margem numeric(7,2);
declare variable valorVenda numeric(13,2);
declare variable percDesc numeric(5,2);
declare variable qtdeItem numeric(10,3);
declare variable qtdeEstq numeric(13,3);
declare variable valorTotal numeric(18,2);
begin /* se o status do pedido estiver como finalizado */
if ((old.status = 'P') and (new.status = 'F')) then
begin /* inclui registro na tabela movimento_estoque */
execute procedure add_movimento_estoque(old.id_pedido,NULL,2,NULL,'N')
returning_values :idMovimento;
/* retorna o último saldo de estoque em que o código do produro e embalagem seja igual ao do item do pedido */
for select s.id_produto, s.id_embalagem, i.valorUnitario, s.percentual,
s.valorVenda, s.percentDesc, s.qtdeAtual, i.quantidade, s.valorTotal
from item_entrada i
inner join saldo_estoque s on(i.id_produto = s.id_produto and
i.id_embalagem = s.id_embalagem)
where (i.id_pedido = old.id_pedido)
and (s.id_movimento = (select max(id_movimento)
from saldo_estoque
where (id_produto = s.id_produto)
and (id_embalagem = s.id_embalagem)))
into :idProduto, :idEmbalagem, :valorCusto, :margem, :valorVenda, :percDesc,
:qtdeEstq, :qtdeItem, :valorTotal
do
begin
execute procedure reajustar_saldoEstq('E',2,:idMovimento,:idProduto,:idEmbalagem,
:qtdeItem,:qtdeEstq,:valorCusto,:margem,
:valorVenda,:percDesc,:valorTotal);
end
end
end ^
set term ; ^
set term ^ ;
create procedure reajustar_saldoEstq(
operacao char(1) character set win1252,
idTipo integer,
idMovimento integer,
idProduto integer,
idEmbalagem integer,
qtde numeric(10,3),
qtdeEstq numeric(13,3),
valorCusto numeric(13,2),
margem numeric(7,2),
valorVenda numeric(13,2),
percDesc numeric(5,2),
valorTotal numeric(18,2))
as
declare variable custoMedio numeric(13,2);
declare variable valorMov numeric(15,2);
begin /* reajusta a quantidade em estoque e o valor total de custo. */
if (operacao in ('E','S','I')) then
begin
if (operacao = 'E') then /* entrada. */
begin
qtdeEstq = (:qtdeEstq + :qtde);
valorMov = (:valorCusto * :qtde);
valorTotal = (:valorTotal + :valorMov);
end
else
if (operacao = 'S') then /* saída. */
begin
qtdeEstq = (:qtdeEstq - :qtde);
valorMov = (:valorCusto * :qtde);
valorTotal = (:valorTotal - :valorMov);
end
else
if (operacao = 'I') then /* inicializa. */
begin
qtdeEstq = :qtde;
valorMov = (:valorCusto * :qtde);
valorTotal = :valorMov;
end
/* inclui registro na tabela saldo_estoque. */
execute procedure add_saldo_estoque (:idMovimento,:idProduto,:idEmbalagem,
:valorCusto,:margem,:valorVenda,:percDesc,
:qtde,:valorMov,:qtdeEstq,:valorTotal);
/* idTipo 2: entrada por compra, 4: devolução de venda, 5: devolução de compra */
/* devolução de ... para casos em que o valor de custo da "devolução" seja diferente do valor de custo atual. */
if ((operacao in ('E','S')) and (idTipo in (2,4,5))) then
begin /* se o custo médio for alterado, recalcula o custo e inclui um novo movimento. */
custoMedio = (:valorTotal / :qtdeEstq);
if (:valorCusto <> :custoMedio) then
begin
execute procedure add_movimento_estoque (NULL,NULL,1,NULL,'N')
returning_values :idMovimento;
execute procedure add_saldo_estoque (:idMovimento,:idProduto,:idEmbalagem,
:custoMedio,:margem,:valorVenda,:percDesc,
0,0,:qtdeEstq,:valorTotal);
end
end
end
end ^
set term ; ^
Pergunta
pestana.
Boa tarde!
Alguma coisa tem de errado neste código eu suspeito que seja esta trigger no bloco For Select ... Into Do, se eu retirar este bloco funciona mas logicamente somente se houver um item por pedido, quando eu adiciono este bloco For Select ... Into Do o erro acontece...
Invalid insert or update value(s): object columns are
constrained - no 2 table rows can have duplicate column values.
violation of PRIMARY or UNIQUE KEY constraint "PK_SALDOESTOQUE" on table "SALDO_ESTOQUE".
Problematic key value is ("ID_MOVIMENTO" = 62, "ID_PRODUTO" = 1, "ID_EMBALAGEM" = 1).
At procedure 'ADD_SALDO_ESTOQUE' line: 15, col: 4
At procedure 'REAJUSTAR_SALDOESTQ' line: 41, col: 8
At trigger 'ADICIONAR_ESTOQUE' line: 34, col: 11.
alguém poderia me dar um Help?
Explicação do código:
Existe as tabelas de pedido_entrada, item_entrada, movimento_estoque e saldo_estoque.
pedido_entrada e item_entrada: armazena os pedidos de compra.
movimento_estoque e saldo_estoque: armazena as movimentações e seu saldo de estoque, respectivamente.
Esta Trigger é disparado depois de atualizar a tabela pedido_entrada (pedido de compra) aonde o campo status for alterado de (P)endente para (F)inalizado.
A inteção é adicionar todos os itens do pedido de compra na tabela saldo de estoque (não esquecendo que a estrutura é um mestre-detalhe movimento_estoque 1-N saldo_estoque).
set term ^ ; create trigger adicionar_estoque for pedido_entrada active after update position 0 as declare variable idMovimento integer; declare variable idProduto integer; declare variable idEmbalagem integer; declare variable valorCusto numeric(13,2); declare variable margem numeric(7,2); declare variable valorVenda numeric(13,2); declare variable percDesc numeric(5,2); declare variable qtdeItem numeric(10,3); declare variable qtdeEstq numeric(13,3); declare variable valorTotal numeric(18,2); begin /* se o status do pedido estiver como finalizado */ if ((old.status = 'P') and (new.status = 'F')) then begin /* inclui registro na tabela movimento_estoque */ execute procedure add_movimento_estoque(old.id_pedido,NULL,2,NULL,'N') returning_values :idMovimento; /* retorna o último saldo de estoque em que o código do produro e embalagem seja igual ao do item do pedido */ for select s.id_produto, s.id_embalagem, i.valorUnitario, s.percentual, s.valorVenda, s.percentDesc, s.qtdeAtual, i.quantidade, s.valorTotal from item_entrada i inner join saldo_estoque s on(i.id_produto = s.id_produto and i.id_embalagem = s.id_embalagem) where (i.id_pedido = old.id_pedido) and (s.id_movimento = (select max(id_movimento) from saldo_estoque where (id_produto = s.id_produto) and (id_embalagem = s.id_embalagem))) into :idProduto, :idEmbalagem, :valorCusto, :margem, :valorVenda, :percDesc, :qtdeEstq, :qtdeItem, :valorTotal do begin execute procedure reajustar_saldoEstq('E',2,:idMovimento,:idProduto,:idEmbalagem, :qtdeItem,:qtdeEstq,:valorCusto,:margem, :valorVenda,:percDesc,:valorTotal); end end end ^ set term ; ^ set term ^ ; create procedure reajustar_saldoEstq( operacao char(1) character set win1252, idTipo integer, idMovimento integer, idProduto integer, idEmbalagem integer, qtde numeric(10,3), qtdeEstq numeric(13,3), valorCusto numeric(13,2), margem numeric(7,2), valorVenda numeric(13,2), percDesc numeric(5,2), valorTotal numeric(18,2)) as declare variable custoMedio numeric(13,2); declare variable valorMov numeric(15,2); begin /* reajusta a quantidade em estoque e o valor total de custo. */ if (operacao in ('E','S','I')) then begin if (operacao = 'E') then /* entrada. */ begin qtdeEstq = (:qtdeEstq + :qtde); valorMov = (:valorCusto * :qtde); valorTotal = (:valorTotal + :valorMov); end else if (operacao = 'S') then /* saída. */ begin qtdeEstq = (:qtdeEstq - :qtde); valorMov = (:valorCusto * :qtde); valorTotal = (:valorTotal - :valorMov); end else if (operacao = 'I') then /* inicializa. */ begin qtdeEstq = :qtde; valorMov = (:valorCusto * :qtde); valorTotal = :valorMov; end /* inclui registro na tabela saldo_estoque. */ execute procedure add_saldo_estoque (:idMovimento,:idProduto,:idEmbalagem, :valorCusto,:margem,:valorVenda,:percDesc, :qtde,:valorMov,:qtdeEstq,:valorTotal); /* idTipo 2: entrada por compra, 4: devolução de venda, 5: devolução de compra */ /* devolução de ... para casos em que o valor de custo da "devolução" seja diferente do valor de custo atual. */ if ((operacao in ('E','S')) and (idTipo in (2,4,5))) then begin /* se o custo médio for alterado, recalcula o custo e inclui um novo movimento. */ custoMedio = (:valorTotal / :qtdeEstq); if (:valorCusto <> :custoMedio) then begin execute procedure add_movimento_estoque (NULL,NULL,1,NULL,'N') returning_values :idMovimento; execute procedure add_saldo_estoque (:idMovimento,:idProduto,:idEmbalagem, :custoMedio,:margem,:valorVenda,:percDesc, 0,0,:qtdeEstq,:valorTotal); end end end end ^ set term ; ^
Obrigado!
Link para o comentário
Compartilhar em outros sites
9 respostass a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.