sql >> Databasteknik >  >> RDS >> Oracle

Count(*) fungerar inte korrekt

Ett par punkter. För det första missbrukar du pragman för autonoma transaktioner. Den är avsedd för separata transaktioner som du behöver utföra eller återställa oberoende av huvudtransaktionen. Du använder den för att återställa huvudtransaktionen -- och du förbinder dig aldrig om det inte finns något fel.

Och de där "oförutsedda konsekvenserna" som någon nämnde? En av dem är att din räkning alltid returnerar 0. Så ta bort pragman både för att den missbrukas och så kommer räkningen att returnera ett korrekt värde.

En annan sak är att inte ha commits eller rollbacks inom triggers. Skapa ett fel och låt den kontrollerande koden göra vad den behöver göra. Jag vet att tillbakadragningarna berodde på pragman. Glöm bara inte att ta bort dem när du tar bort pragman.

Följande trigger fungerar för mig:

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;

Det är dock inte en bra idé för en utlösare på ett bord att separat komma åt den tabellen. Vanligtvis tillåter systemet inte ens det -- denna utlösare kommer inte att köras alls om den ändras till "efter". Om det är tillåtet att exekvera, kan man aldrig vara säker på de resultat som erhållits - som du redan har upptäckt. Jag är faktiskt lite förvånad över att triggern ovan fungerar. Jag skulle känna mig obekväm med att använda den i en riktig databas.

Det bästa alternativet när en utlösare måste komma åt måltabellen är att gömma tabellen bakom en vy och skriva en "istället för" trigger på vyn. Det trigger kan komma åt tabellen allt den vill.



  1. OUTPUT-klausul i MySQL

  2. Hur man använder paginering med laravel DB::select-fråga

  3. ORA-00936 När du använder datumfunktionen i oracle select-satsen

  4. Ändra kolumnordning i tabellen över postgres