sql >> Database >  >> RDS >> Oracle

Een PL/SQL-rijtrigger maken die een kolom uit een andere tabel valideert?

Er zijn verschillende problemen met uw trigger. Laten we beginnen met de 'relatie' tussen een select statement en de resterende code. In dit specifieke geval de select.. en de if...end_if (voorlopig neem je aan dat je select echt werkt, dat doet het niet, maar ga er maar vanuit). Concentreer je nu op de WHERE-clausule.

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

IF TRUST = 'NO' THEN ...

Aangezien uw select ALLEEN JA retourneert, zal de if-instructie nooit waar zijn. Daarom kan de toepassingsuitzondering nooit worden opgeworpen. Wat zijn nu de problemen met de select .
Eerst ga je naar de tafel waarop de trigger is geactiveerd. In sommige gevallen kun je ermee wegkomen, maar meestal resulteert dit in een ORA -04091:tabel muteert, trigger/functie ziet het mogelijk niet . Het is een mislukking om altijd te voorkomen dat u helemaal naar de activeringstabel verwijst. U verwijst naar de tabelgegevens met de :NEW en/of :OLD pseudo-records. Ten tweede doet uw vraag niet wat u denkt dat het is. Er staat

De INTO-clausule vereist echter dat de instructie precies 1 rij . teruggeeft . Meer dan 1 rij resulteert in de uitzondering en 0 rijen resulteert in een no data found uitzondering.
Eindelijk is er een probleem met de raise_application_error statement . Als het zou worden uitgevoerd, zou het een getalargument opwerpen... is buiten bereik uitzondering. De eerste parameter moet tussen -20999 en -20000 liggen (negatief getal). Dus hoe ziet het resultaat eruit:

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

OPMERKINGEN:
Gebruik geen gegevenstype VARCHAR. Het is toegestaan, maar Oracle raadt het af. Dit betekent dat ze zich het recht voorbehouden om op elk moment te veranderen wat het doet. Gebruik in plaats daarvan de aanbevolen VARCHAR2.
Ik verander de trigger om te vuren op Insert of Update. Bij ontslag op Insert KAN alleen iemand de naam van de leverancier wijzigen om te verwijzen naar een niet-vertrouwde leverancier en alles zou in orde zijn.



  1. Hoe bereken je dagen tussen twee datums in PHP?

  2. Voer deze bedrijfsurenquery uit in PostgreSQL

  3. MySQL &Java - Krijg id van de laatst ingevoerde waarde (JDBC)

  4. met behulp van sqlldr van java