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

Używanie JEŻELI ISTNIEJE (WYBIERZ...) w wyzwalaczu PRZED WSTAWIANIEM (Oracle)

Po pierwsze, jeśli używasz SQL*Plus, kiedy tworzysz obiekt i pojawia się informacja o błędach kompilacji, polecenie show errors pokaże ci błędy.

Jeśli uruchomiłeś show errors , zostaniesz poinformowany, że IF EXISTS nie jest poprawną składnią. Możesz zrobić coś takiego

SELECT COUNT(*)
  INTO l_cnt
  FROM <<rest of query>>

IF( l_cnt > 0 )
THEN
  RAISE_APPLICATION_ERROR ...
END IF;

Jednak po naprawieniu błędu kompilacji wystąpią błędy w czasie wykonywania. W wyzwalaczu na poziomie wiersza w surveillance , generalnie nie można wykonać zapytania surveillance (możesz, jeśli wszystko, co robisz, to INSERT VALUES co gwarantuje wstawienie tylko jednego wiersza). Jeśli to zrobisz, otrzymasz błąd wyzwalacza mutacji w czasie wykonywania.

Z perspektywy modelu danych, gdy projektujesz tabelę, w której prawidłowe dane dla określonego wiersza zależą od danych przechowywanych w innych wierszach tej samej tabeli, generalnie naruszasz zasady normalizacji i generalnie lepiej radzisz sobie z naprawą bazowy model danych.

Jeśli jesteś naprawdę zdeterminowany, aby zachować model danych, wolałbym utworzyć zmaterializowany widok, który odświeża się po zatwierdzeniu, który zawiera dane tylko dla wierszy, które naruszają twoje kryteria. Następnie możesz nałożyć ograniczenia na ten zmaterializowany widok, które generują błędy w czasie zatwierdzania, gdy zostaną naruszone kryteria. Będzie to wymagało dzienników widoków zmaterializowanych na Twoim stole.

Jeśli naprawdę chcesz zachować model danych i chcesz wymusić logikę za pomocą wyzwalaczy, potrzebujesz klasycznego rozwiązania z trzema wyzwalaczami (lub wyzwalacza złożonego z trzema częściami, jeśli używasz wersji 11.2 lub nowszej). Utworzyłbyś pakiet z kolekcją wartości klucza podstawowego. Wyzwalacz instrukcji before zainicjuje kolekcję. Wyzwalacz na poziomie wiersza wstawia klucze podstawowe wierszy, które zostały wstawione i/lub zaktualizowane do tej kolekcji. A następnie wyzwalacz instrukcji after iteruje po tej kolekcji i implementuje dowolne sprawdzenia. To jednak dużo ruchomych elementów, dlatego generalnie odradzam.

Dodatkowo, nawet jeśli wszystkie te elementy będą działać, Twoja logika nie ochroni Cię w środowisku wielu użytkowników. Kiedy do systemu wchodzi wielu użytkowników w tym samym czasie, jest całkowicie możliwe, że jeden użytkownik wstawi wiersz, drugi użytkownik wstawi kolejny wiersz z nakładającym się zakresem, a następnie każda sesja zostanie zatwierdzona. W takim przypadku oba zestawy wyzwalaczy pozwolą na zmianę, ale nadal pozostaną dane w tabeli, które naruszają Twoje wymagania. Widok zmaterializowany, ponieważ jest wymuszany w czasie zatwierdzania, a nie w czasie wstawiania, będzie działał poprawnie w środowisku wielu użytkowników. Jeśli chcesz, aby wyzwalacze działały w środowisku wielu użytkowników, musisz je dodatkowo skomplikować, dodając dodatkową logikę, która wymusza serializację, która blokuje insert drugiej sesji od uruchomienia do pierwszej sesji zatwierdzonej lub wycofanej. To dodaje złożoności, zmniejsza skalowalność i, w zależności od tego, jak jest zaimplementowane, może stać się koszmarem wsparcia.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Połącz się z bazą danych Oracle w VB

  2. Dane wyjściowe Oracle różnią się w SQL Developer i Excel

  3. Skąd można dowiedzieć się o przestarzałych funkcjach nowej wersji Oracle?

  4. Boże Narodzenie przychodzi wcześnie (Oracle 12.2)

  5. Oracle SqlPlus - zapisywanie danych wyjściowych w pliku, ale nie wyświetla się na ekranie