PLS - 00306在运行程序的触发器内

时间:2014-12-16 02:41:30

标签: sql oracle stored-procedures

我正在尝试编译执行​​过程的触发器时获得PLS - 00306。

以下是该程序的代码:

CREATE OR REPLACE PROCEDURE FRANCISCO.PRO_ATUALIZAPRECO_CUSTO (P_PRO   IN FRANCISCO.MOVIMENTACAO.ID_PRODUTO%TYPE, P_ERRO  OUT VARCHAR2)

IS
   V_COUNT  NUMBER                         := NULL;
   V_VALOR  NUMBER(19,6)                   := NULL;
   V_QTDE   NUMBER(19,6)                   := NULL;
   V_CUSTO  NUMBER(19,6)                   := NULL;
   ERRO01   EXCEPTION;
BEGIN
   P_ERRO  := NULL;

   IF P_PRO IS NULL THEN
      P_ERRO := 'Produto precisa ser informado.';
      RAISE ERRO01;   
   END IF;

   V_VALOR := 0;
   V_QTDE  := 0;
   FOR S_1 IN (SELECT QUANTIDADE, (CUSTO_TOTAL + FRETE) VALOR, UPPER(TIPO) TIPO
               FROM FRANCISCO.MOVIMENTACAO 
               WHERE ID_PRODUTO = P_PRO
               ORDER BY DATA_EMISSAO,TIPO)
   LOOP                       
      IF S_1.TIPO = 'E' THEN
         V_VALOR := V_VALOR + S_1.VALOR;
         V_QTDE  := V_QTDE + S_1.QUANTIDADE;
      ELSE
         V_VALOR := V_VALOR - S_1.VALOR;
         V_QTDE  := V_QTDE - S_1.QUANTIDADE;
      END IF;
      IF V_VALOR > 0 AND V_QTDE > 0 THEN
         V_CUSTO := V_VALOR / V_QTDE;
      END IF;
   END LOOP;

   IF V_CUSTO > 0 THEN
      UPDATE FRANCISCO.PRODUTOS
      SET PRECO_CUSTO = V_CUSTO
      WHERE ID = P_PRO;
   END IF;

   COMMIT;   

EXCEPTION
   WHEN ERRO01 THEN
      ROLLBACK;

   WHEN OTHERS THEN
      P_ERRO := SUBSTR(SQLERRM,1,1000);
      ROLLBACK;
END;
   /

触发器的代码如下:

create or replace trigger t_atualizacusto
after insert on FRANCISCO.MOVIMENTACAO
referencing old as old new as new
for each row
declare
cod_produto FRANCISCO.MOVIMENTACAO.ID_PRODUTO%type := null;
begin
    select id_produto
    into cod_produto
    from FRANCISCO.MOVIMENTACAO
    where id_produto = :new.id_produto;

    exec FRANCISCO.PRO_ATUALIZAPRECO_CUSTO(cod_produto);

    commit;
end;

我做错了什么?我应该为p_erro参数设置一个值吗?
谢谢,这将是一个很好的帮助:)

1 个答案:

答案 0 :(得分:1)

您需要声明out参数占位符:

create or replace trigger t_atualizacusto
after insert on FRANCISCO.MOVIMENTACAO
referencing old as old new as new
for each row
declare
cod_produto FRANCISCO.MOVIMENTACAO.ID_PRODUTO%type := null;
d_error varchar2(256); -- or whatever size needed
begin
    select id_produto
    into cod_produto
    from FRANCISCO.MOVIMENTACAO
    where id_produto = :new.id_produto;

    FRANCISCO.PRO_ATUALIZAPRECO_CUSTO(cod_produto, d_error);

end;