sql >> Base de Datos >  >> RDS >> Oracle

¿Es esto posible en Oracle/Sql?

Un par de comentarios sobre el DDL que publicaste.

  • No hay AUTOINCREMENT palabra clave en Oracle. Debería crear una secuencia (generalmente una secuencia por tabla) y usar NEXTVAL de la secuencia ya sea en el INSERT instrucción en sí misma o en un activador para completar la clave primaria sintética.
  • No hay nada que esté creando un VENUE_NO columna en EVENT_DETAILS . Supongo que su DDL real está definiendo esa columna.

No puede hacer cumplir esto a través de un simple CHECK restricción. Puedes crear un disparador

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;

Tenga en cuenta, sin embargo, que

  • También necesitaría tener un disparador en el VENUE tabla que verifica si los cambios en la capacidad del lugar causan que ciertos eventos dejen de ser válidos. En general, eso requeriría que haya algún tipo de fecha en la tabla de detalles del evento ya que, presumiblemente, la capacidad de un lugar puede cambiar con el tiempo y realmente solo desea la validación para verificar futuros eventos en ese lugar.
  • Las soluciones basadas en activadores no siempre funcionarán en entornos multiusuario. Imagine que el lugar 1 tiene una capacidad de 30. Ahora, la sesión A actualiza esa capacidad a 15. Pero antes de que la sesión A se comprometa, la sesión B inserta un evento con NO_PLAYERS de 20. Ninguno de los activadores de sesión detectará un problema, por lo que se permitirán ambos cambios. Pero una vez que ambas sesiones se comprometan, habrá un evento reservado con 20 jugadores en un lugar que solo admite 15 jugadores. El disparador en EVENT_DETAILS potencialmente podría bloquear la fila en el VENUE para evitar esta condición de carrera, pero está serializando inserciones y actualizaciones en EVENT_DETAILS tabla que podría ser un problema de rendimiento, especialmente si su aplicación alguna vez espera la entrada humana antes de realizar una transacción.

Como alternativa a los disparadores, puede crear un ON COMMIT vista materializada que une las dos tablas y coloca un CHECK restricción en esa vista materializada que impone el requisito de que el número de jugadores no puede exceder la capacidad del lugar. Eso funcionará en un entorno multiusuario, pero requiere registros de vista materializados en ambas tablas base y mueve la verificación al punto donde se confirman las sesiones, lo que puede ser un poco complicado. La mayoría de las aplicaciones no consideran la posibilidad de que un COMMIT La declaración podría fallar, por lo que manejar esas excepciones puede ser complicado. Y desde el punto de vista de la interfaz de usuario, puede ser algo complicado explicarle al usuario cuál es el problema, ya que la excepción puede estar relacionada con cambios realizados mucho antes en la transacción.