sql >> Database >  >> RDS >> Oracle

Count(*) werkt niet goed

Een paar punten. Ten eerste misbruik je het autonome transactiepragma. Het is bedoeld voor afzonderlijke transacties die u onafhankelijk van de hoofdtransactie moet vastleggen of terugdraaien. Je gebruikt het om de hoofdtransactie terug te draaien -- en je pleegt nooit als er geen fout is.

En die "onvoorziene gevolgen" die iemand noemde? Een daarvan is dat je telling altijd 0 retourneert. Dus verwijder het pragma zowel omdat het wordt misbruikt als de telling een juiste waarde retourneert.

Een ander ding is dat je geen commits of rollbacks hebt binnen triggers. Geef een foutmelding en laat de controlerende code doen wat hij moet doen. Ik weet dat de terugdraaiingen waren vanwege het pragma. Vergeet ze niet te verwijderen wanneer u het pragma verwijdert.

De volgende trigger werkt voor mij:

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;

Het is echter geen goed idee voor een trigger op een tafel om afzonderlijk toegang te krijgen tot die tabel. Meestal staat het systeem het niet eens toe -- deze trigger wordt helemaal niet uitgevoerd als deze wordt gewijzigd in "na". Als het is toegestaan ​​om uit te voeren, kan men nooit zeker zijn van de verkregen resultaten - zoals u al ontdekte. Eigenlijk ben ik een beetje verbaasd dat de bovenstaande trigger werkt. Ik zou me ongemakkelijk voelen als ik het in een echte database zou gebruiken.

De beste optie wanneer een trigger moet toegang tot de doeltabel is om de tabel achter een weergave te verbergen en een "in plaats van" trigger op de weergave te schrijven. Dat trigger heeft toegang tot de tafel zoveel hij wil.



  1. Negeert MySQL null-waarden op unieke beperkingen?

  2. Sorteer een tekstaggregaat gemaakt met array_agg in postgresql

  3. Voeg twee mysql-tabellen samen

  4. MySQL-gedrag van ON DUPLICATE KEY UPDATE voor meerdere UNIEKE velden