Multiple rows in singleton select Firebird 2.1

17/01/2013

29

Bom dia, migrei meu banco do firebird 1.5 para 2.1 e comecei a ter alguns problemas, alguns consegui resolver mas outros estão me dando dor de cabeça.
Tenho a seguinte trigger :
CREATE OR ALTER trigger movimento_itens_ai1 for movimento_itens
active after insert position 0
as
 DECLARE VARIABLE TIPO CHAR(1) CHARACTER SET WIN1252;
begin

 UPDATE PRODUTOS SET QTD = 0
 WHERE QTD IS NULL;

select 
    produtos.tipo
from produtos
   inner join movimento_itens on (produtos.cod_prod = movimento_itens.cod_prod)
 INTO :TIPO;

 if (:TIPO = 'P') then
  begin
   EXECUTE PROCEDURE ATUALIZA_PRODUTOS new.cod_mov,
   new.COD_PROD, new.VALOR, new.QTD,
   new.ICMS, new.IPI, new.TIPO;
  end
end


A trigger chama a seguinte procedure :

SET TERM ^ ;

create or alter procedure ATUALIZA_PRODUTOS (
    COD_MOV integer,
    COD_PROD varchar(25),
    VL numeric(18,2),
    QTD_ENT integer,
    ICMS numeric(18,2),
    IPI numeric(18,2),
    TIPO char(1))
as
declare variable TP_MOV char(1);
declare variable CLC_VENDA char(1);
declare variable CLC_COMPRA char(1);
declare variable ESTOQUE integer;
declare variable CUSTO_MEDIO_A numeric(18,2);
declare variable CUSTO_ATUAL numeric(18,2);
declare variable LUCRO numeric(18,2);
begin

 UPDATE PRODUTOS SET QTD = 0
 WHERE QTD IS NULL;

 SELECT M.TIPO_MOV FROM MOVIMENTO M WHERE M.COD_MOV = :COD_MOV
 INTO :TP_MOV;

 if (:TP_MOV = 'E') then
 BEGIN

  if (:ICMS IS NULL) then
   ICMS = 0.00;
  if (:IPI IS NULL) then
   IPI = 0.00;

  CUSTO_ATUAL = VL+(((VL*ICMS)/100)+((VL*IPI)/100));

  SELECT P.QTD,P.VL_CUSTO_MEDIO FROM PRODUTOS P
   where P.COD_PROD = :COD_PROD
    INTO :ESTOQUE,:CUSTO_MEDIO_A;

  if (custo_medio_a IS NULL) then
   CUSTO_MEDIO_A = 0;

  SELECT PR.CALCULA_VL_VENDA,
   PR.ATUALIZA_VL_COMPRA,PR.margem_lucro FROM PARAMETROS PR
    INTO :CLC_VENDA,:CLC_COMPRA,:LUCRO;

  if (CLC_COMPRA = 'T') then
   UPDATE PRODUTOS P3 set P3.VL_COMPRA = :VL,
    P3.vl_custo = :CUSTO_ATUAL,P3.ICMS = :ICMS,
    P3.ipi = :IPI where P3.cod_prod = :COD_PROD;

  UPDATE PRODUTOS P4 SET P4.vl_custo_medio =
   ((:ESTOQUE * :custo_medio_A)+(:QTD_ENT * :CUSTO_ATUAL))/
    (:ESTOQUE + :QTD_ENT),P4.QTD = P4.QTD + :QTD_ENT
     WHERE P4.COD_PROD = :COD_PROD;

  if (CLC_VENDA = 'T') then
   BEGIN
    if (LUCRO IS NULL) then
     LUCRO = 0;
    UPDATE PRODUTOS P2 set p2.valor = :CUSTO_ATUAL+
    ((:CUSTO_ATUAL*:LUCRO)/100)
     where p2.cod_prod = :cod_prod;
   END

 END /* TP = 'E' */

 ELSE
 if (:tipo = '-') then
  UPDATE PRODUTOS P2 set p2.qtd = p2.qtd - :qtd_ENT
   where p2.cod_prod = :cod_prod;
 ELSE
 if (:tipo = '+') then
  UPDATE PRODUTOS P3 set p3.qtd = p3.qtd + :qtd_ENT
   where p3.cod_prod = :cod_prod;

 suspend;
end^

SET TERM ; ^

/* Following GRANT statetements are generated automatically */

GRANT SELECT,UPDATE ON PRODUTOS TO PROCEDURE ATUALIZA_PRODUTOS;
GRANT SELECT ON MOVIMENTO TO PROCEDURE ATUALIZA_PRODUTOS;
GRANT SELECT ON PARAMETROS TO PROCEDURE ATUALIZA_PRODUTOS;

/* Existing privileges on this procedure */

GRANT EXECUTE ON PROCEDURE ATUALIZA_PRODUTOS TO SYSDBA;


Então ao executar a trigger obtenho o erro citado acima.

Agradeço desde já qualquer ajuda.

Alexandre Torres
Responder

Posts

17/01/2013

Junior Miranda

Observe este select seu:

select 
produtos.tipo
from produtos
inner join movimento_itens on (produtos.cod_prod = movimento_itens.cod_prod)
INTO :TIPO;


O problema não é ele, não?? Estruturalmente, ele poderá retornar mais de uma linha... Então, não seria melhor usar um cursor??

[]´s
Responder
Observe este select seu:

select 
produtos.tipo
from produtos
inner join movimento_itens on (produtos.cod_prod = movimento_itens.cod_prod)
INTO :TIPO;


O problema não é ele, não?? Estruturalmente, ele poderá retornar mais de uma linha... Então, não seria melhor usar um cursor??

[]´s


Perfeito Junior Miranda, nada que um for não resolvesse.

Muito obrigado pela ajuda.
Responder