Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Count(*) não está funcionando corretamente


Alguns pontos. Primeiro, você está usando mal o pragma de transação autônoma. Destina-se a transações separadas que você precisa confirmar ou reverter independentemente da transação principal. Você o está usando para reverter a transação principal - e você nunca confirma se não houver erro.

E aquelas "consequências imprevistas" que alguém mencionou? Uma delas é que sua contagem sempre retorna 0. Portanto, remova o pragma tanto porque está sendo mal utilizado e assim a contagem retornará um valor adequado.

Outra coisa é não ter commits ou rollbacks dentro de triggers. Gere um erro e deixe o código de controle fazer o que precisa fazer. Eu sei que as reversões foram por causa do pragma. Só não se esqueça de removê-los quando você remover o pragma.

O seguinte gatilho funciona para mim:
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;

No entanto, não é uma boa ideia que um gatilho em uma tabela acesse essa tabela separadamente. Normalmente, o sistema nem permite isso - esse gatilho não será executado se for alterado para "depois". Se for permitido executar, nunca se pode ter certeza dos resultados obtidos - como você já descobriu. Na verdade, estou um pouco surpreso que o gatilho acima funcione. Eu me sentiria desconfortável ao usá-lo em um banco de dados real.

A melhor opção quando um gatilho deve acessar a tabela de destino é ocultar a tabela atrás de uma visão e escrever um gatilho "em vez de" na visão. Isso o gatilho pode acessar a tabela o quanto quiser.