Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment créer un déclencheur de ligne PL/SQL qui valide une colonne d'une autre table

Il y a plusieurs problèmes avec votre déclencheur. Commençons par la "relation" entre une instruction select et le code restant. Dans ce cas particulier, le select.. et le if...end_if (pour le moment, supposons que votre sélection fonctionne réellement, ce n'est pas le cas, mais supposez simplement). Concentrez-vous maintenant sur la clause WHERE.

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

IF TRUST = 'NO' THEN ...

Puisque votre sélection renvoie UNIQUEMENT OUI, l'instruction if ne sera jamais True. Par conséquent, l'exception d'application ne peut jamais être déclenchée. Maintenant, quels sont les problèmes avec le select .
Eh bien, vous accédez d'abord à la table sur laquelle le déclencheur est déclenché. Alors que dans certains cas, vous pouvez vous en tirer, mais cela se traduit généralement par un ORA -04091 :la table est en train de muter, le déclencheur/la fonction peut ne pas la voir . Il est préférable d'éviter de toujours faire référence à la table de déclenchement. Vous référencez les données de la table avec les pseudo-enregistrements :NEW et/ou :OLD. Deuxièmement, votre requête ne fait pas ce que vous pensez qu'elle est. Il dit

Cependant, la clause INTO exige que l'instruction renvoie exactement 1 ligne . Plus de 1 ligne entraîne l'exception et 0 ligne entraîne un no data found exception.
Enfin, il y a un problème avec l'instruction raise_application_error statement . S'il était exécuté, il lèverait un argument de nombre... est hors limites exception. Le premier paramètre doit être compris entre -20999 et -20000 (nombre négatif). Alors, à quoi ressemble le résultat :

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

REMARQUES :
N'UTILISEZ PAS le type de données VARCHAR. C'est autorisé mais Oracle le déconseille. Cela signifie qu'ils se réservent le droit de modifier ce qu'il fait à tout moment. Utilisez plutôt le VARCHAR2 recommandé.
Je modifie le déclencheur pour qu'il se déclenche lors de l'insertion ou de la mise à jour. S'il est renvoyé sur Insérer, seul quelqu'un PEUT modifier le nom_du_fournisseur pour référencer un fournisseur non fiable et tout irait bien.