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

Isso é possível no Oracle/Sql?


Alguns comentários sobre o DDL que você postou.
  • Não há AUTOINCREMENT palavra-chave no Oracle. Você precisaria criar uma sequência (geralmente uma sequência por tabela) e usar o NEXTVAL da sequência no INSERT própria instrução ou em um gatilho para preencher a chave primária sintética.
  • Não há nada que esteja criando um VENUE_NO coluna em EVENT_DETAILS . Presumo que seu DDL real esteja definindo essa coluna.

Você não pode impor isso através de um simples CHECK restrição. Você pode criar um gatilho
CREATE OR REPLACE TRIGGER validate_capacity
  BEFORE INSERT OR UPDATE ON event_details
  FOR EACH ROW
DECLARE
  l_venue_capacity venue.capacity%type;
BEGIN
  SELECT capacity
    INTO l_venue_capacity
    FROM venue
   WHERE venue_no = :new.venue_no;

  IF( l_venue_capacity < :new.no_players )
  THEN
    RAISE_APPLICATION_ERROR( -20001, 'Sorry, the venue has insufficient capacity' );
  END IF;
END;

Esteja ciente, no entanto, que
  • Você também precisaria ter um acionador no VENUE tabela que verifica se as alterações na capacidade do local fazem com que determinados eventos se tornem inválidos. Geralmente, isso exigiria que houvesse algum tipo de data na tabela de detalhes do evento, pois, presumivelmente, a capacidade de um local pode mudar com o tempo e você realmente deseja que a validação verifique apenas eventos futuros nesse local.
  • As soluções baseadas em gatilho nem sempre funcionam em ambientes multiusuário. Imagine que o local 1 tenha uma capacidade de 30. Agora, a sessão A atualiza essa capacidade para 15. Mas antes da sessão A ser confirmada, a sessão B insere um evento com um NO_PLAYERS de 20. Nenhum acionador de sessão verá um problema, portanto, ambas as alterações serão permitidas. Mas assim que ambas as sessões forem confirmadas, haverá um evento reservado com 20 jogadores em um local que suporta apenas 15 jogadores. O acionador em EVENT_DETAILS poderia bloquear a linha no VENUE table para evitar essa condição de corrida, mas você está serializando inserções e atualizações no EVENT_DETAILS table, o que pode ser um problema de desempenho, especialmente se seu aplicativo sempre aguardar a entrada humana antes de confirmar uma transação.

Como alternativa aos gatilhos, você pode criar um ON COMMIT visão materializada que une as duas tabelas e coloca um CHECK restrição nessa visão materializada que impõe a exigência de que o número de jogadores não pode exceder a capacidade do local. Isso funcionará em um ambiente multiusuário, mas requer logs de visualização materializados em ambas as tabelas base e move a verificação para o ponto em que as sessões são confirmadas, o que pode ser um pouco complicado. A maioria dos aplicativos não considera a possibilidade de um COMMIT pode falhar, portanto, lidar com essas exceções pode ser complicado. E do ponto de vista da interface do usuário, pode ser um pouco complicado explicar ao usuário qual é o problema, pois a exceção pode estar relacionada a alterações feitas muito mais cedo na transação.