Oracle
 sql >> Database >  >> RDS >> Oracle

Come creare un trigger di riga PL/SQL che convalida una colonna da un'altra tabella

Ci sono diversi problemi con il tuo trigger. Iniziamo con la "relazione" tra un'istruzione select e il codice rimanente. In questo caso particolare il select.. e il if...end_if (per il momento supponiamo che il tuo select funzioni effettivamente, non lo fa ma presuppone). Ora concentrati sulla clausola WHERE.

SELECT SUPPLIER.TRUSTED_SUPPLIER
    INTO TRUST
    ...
    WHERE SUPPLIER.TRUSTED_SUPPLIER = 'YES';

IF TRUST = 'NO' THEN ...

Poiché la tua selezione restituisce SOLO SÌ, l'istruzione if non sarà mai True. Pertanto l'eccezione dell'applicazione non può mai essere sollevata. Ora, quali sono i problemi con select .
Bene, prima stai accedendo alla tabella su cui viene attivato il trigger. Mentre in alcuni casi puoi farla franca, ma di solito si traduce in un ORA -04091:la tabella sta mutando, il trigger/la funzione potrebbe non vederlo . È sbagliato evitare sempre del tutto di fare riferimento alla tabella di attivazione. Si fa riferimento ai dati della tabella con gli pseudo record :NEW e/o :OLD. In secondo luogo, la tua domanda non sta facendo quello che pensi che sia. Dice

Tuttavia, la clausola INTO richiede che l'istruzione restituisca esattamente 1 riga . Più di 1 riga genera l'eccezione e 0 righe genera un no data found eccezione.
Infine c'è un problema con l'raise_application_error statement . Se fosse eseguito, solleverebbe un argomento numerico... è fuori intervallo eccezione. Il primo parametro deve essere compreso tra -20999 e -20000 (numero negativo). Quindi, qual è il risultato:

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;
/

NOTE:
NON utilizzare il tipo di dati VARCHAR. È consentito ma Oracle lo sconsiglia. Significa che si riservano il diritto di cambiare ciò che fa in qualsiasi momento. Utilizzare invece il VARCHAR2 consigliato.
Cambio il trigger in modo che si attivi su Inserisci o Aggiorna. Se attivato su Inserisci solo qualcuno PUÒ modificare il nome_fornitore per fare riferimento a un fornitore non affidabile e tutto andrebbe bene.