Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Jak utworzyć wyzwalacz wiersza PL/SQL, który sprawdza poprawność kolumny z innej tabeli?

Istnieje kilka problemów z wyzwalaczem. Zacznijmy od „związku” między instrukcją select a pozostałym kodem. W tym konkretnym przypadku select.. i if...end_if (na razie załóżmy, że twój wybór rzeczywiście działa, to nie tylko założenie). Teraz skoncentruj się na klauzuli WHERE.

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

IF TRUST = 'NO' THEN ...

Ponieważ wybór zwraca TYLKO TAK, instrukcja if nigdy nie będzie True. Dlatego nigdy nie można zgłosić wyjątku aplikacji. Jakie są problemy z select .
No cóż, najpierw uzyskujesz dostęp do tabeli, w której uruchamiany jest wyzwalacz. Chociaż w niektórych przypadkach może to ujść na sucho, zwykle skutkuje to ORA -04091:tabela mutuje, wyzwalacz/funkcja może jej nie widzieć . Nie ma sensu, aby zawsze całkowicie unikać odwoływania się do tabeli wyzwalającej. Odwołujesz się do danych tabeli za pomocą pseudo rekordów :NEW i/lub :OLD. Po drugie, twoje zapytanie nie robi tego, co myślisz, że jest. Mówi

Jednak klauzula INTO wymaga, aby instrukcja zwracała dokładnie 1 wiersz . Więcej niż 1 wiersz powoduje wyjątek, a 0 wierszy oznacza no data found wyjątek.
Nareszcie pojawił się problem z instrukcją raise_application_error statement . Gdyby został wykonany, podniósłby argument liczbowy... jest poza zakresem wyjątek. Pierwszy parametr musi zawierać się w przedziale od -20999 do -20000 (liczba ujemna). Jak więc wygląda wynik:

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

UWAGI:
Nie używaj typu danych VARCHAR. Jest to dozwolone, ale Oracle odradza to. Oznacza to, że zastrzegają sobie prawo do zmiany tego, co robi w dowolnym momencie. Zamiast tego użyj zalecanego VARCHAR2.
Zmieniam wyzwalacz, aby uruchamiał się po wstawieniu lub aktualizacji. W przypadku uruchomienia w trybie Insert tylko ktoś MOŻE zmienić nazwę dostawcy, aby odwoływać się do niezaufanego dostawcy i wszystko będzie dobrze.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Szyfrowanie wewnątrz wyroczni

  2. Obraz w formacie daty Oracle kończy się przed konwersją całego ciągu wejściowego

  3. Używanie CONTINUE In Loops do wznowienia kontroli w Oracle

  4. Utwórz plik wyjściowy w formacie płaskim o stałej szerokości z zapytania SQL

  5. SQL:jak korzystać z UNION i zamawiać według konkretnego wyboru?