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

Count (*) nie działa poprawnie

Kilka punktów. Po pierwsze, nadużywasz autonomicznej pragma transakcyjnej. Jest przeznaczony do oddzielnych transakcji, które musisz zatwierdzić lub wycofać niezależnie od głównej transakcji. Używasz go do wycofania głównej transakcji - i nigdy nie zatwierdzasz, jeśli nie ma błędu.

A te „nieprzewidziane konsekwencje”, o których ktoś wspomniał? Jednym z nich jest to, że licznik zawsze zwraca 0. Usuń pragmę, ponieważ jest ona niewłaściwie używana, a licznik zwróci prawidłową wartość.

Inną rzeczą jest brak zatwierdzeń lub cofnięć w wyzwalaczach. Zgłoś błąd i pozwól kodowi sterującemu zrobić to, co musi. Wiem, że wycofania były spowodowane pragmą. Tylko nie zapomnij o ich usunięciu, gdy usuniesz pragmę.

Dla mnie działa następujący wyzwalacz:

CREATE OR REPLACE TRIGGER trg_mytable_biu 
BEFORE INSERT OR UPDATE ON mytable 
FOR EACH ROW 
WHEN (NEW.TYPEB = 'Bert') -- Don't even execute unless this is Bert
DECLARE
    L_COUNT NUMBER;
BEGIN
    SELECT  COUNT(*) INTO L_COUNT
    FROM    MYTABLE 
    WHERE   ARTICLE = :NEW.ARTICLE
        AND TYPEB = :NEW.TYPEB;

    IF L_COUNT > 0  THEN
        RAISE_APPLICATION_ERROR( -20001, 'Bert already exists!' );
    ELSIF :NEW.STOCK_COUNT > 1 THEN
        RAISE_APPLICATION_ERROR( -20001, 'Can''t insert more than one Bert!' );
    END IF;
END;

Jednak nie jest dobrym pomysłem, aby wyzwalacz w tabeli miał osobny dostęp do tej tabeli. Zwykle system nawet na to nie pozwala -- ten wyzwalacz w ogóle się nie uruchomi, jeśli zostanie zmieniony na „po”. Jeśli jest to dozwolone do wykonania, nigdy nie można być pewnym uzyskanych wyników – jak już się dowiedziałeś. Właściwie jestem trochę zaskoczony, że powyższy wyzwalacz działa. Czułbym się nieswojo, używając go w prawdziwej bazie danych.

Najlepsza opcja, gdy wyzwalacz musi dostęp do tabeli docelowej polega na ukryciu tabeli za widokiem i napisaniu wyzwalacza „zamiast” w widoku. To wyzwalacz może uzyskać dostęp do tabeli, ile tylko chce.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Porównaj dwa rekordy i pokaż tylko różnicę

  2. Dlaczego Oracle zwraca określoną sekwencję, jeśli wartości „orderby” są identyczne?

  3. Nieprawidłowy operator relacyjny

  4. PLS-00306:błędna liczba lub typy argumentów w wezwaniu do

  5. Czy istnieje sposób na zainstalowanie Javy na Oracle 11g XE?