Existem vários problemas com o seu gatilho. Vamos começar com o 'relacionamento' entre uma instrução select e o código restante. Neste caso em particular, o
select..
e o if...end_if
(no momento, suponha que seu select realmente funcione, ele não funciona, mas apenas assume). Agora concentre-se na cláusula WHERE. SELECT SUPPLIER.TRUSTED_SUPPLIER
INTO TRUST
...
WHERE SUPPLIER.TRUSTED_SUPPLIER = 'YES';
IF TRUST = 'NO' THEN ...
Como seu select retorna SOMENTE YES, a instrução if nunca será True. Portanto, a exceção do aplicativo nunca pode ser levantada. Agora, quais são os problemas com o
select
. Bem, primeiro você está acessando a tabela na qual o gatilho é disparado. Embora em alguns casos você possa se safar, mas geralmente resulta em um ORA -04091:a tabela
No entanto, a cláusula INTO exige que a instrução retorne exatamente 1 linha . Mais de 1 linha resulta na exceção e 0 linha resulta em um
no data found
exceção. Finalmente, há um problema com a
raise_application_error statement
. Se fosse executado, geraria um argumento de número... está fora do intervalo exceção. O primeiro parâmetro deve estar entre -20999 a -20000 (número negativo). Então, como é o resultado:create or replace trigger verify_supplier_trust
before insert or update on product
for each row
declare
trust varchar2(3);
begin
select supplier.trusted_supplier
into trust
from supplier
where supplier.company_name = :new.supplier_name
and supplier.trusted_supplier = 'YES';
exception
when no_data_found then
raise_application_error(-20001, 'supplier not trusted');
end;
/
NOTAS:
Não use o tipo de dados VARCHAR. É permitido, mas a Oracle não recomenda. Significa que eles estão se reservando o direito de mudar o que faz a qualquer momento. Em vez disso, use o VARCHAR2 recomendado.
Eu mudo o gatilho para disparar em Insert ou Update. Se acionado em Inserir, apenas alguém PODE alterar o nome_do_fornecedor para fazer referência a um fornecedor não confiável e tudo ficará bem.