Is this possible in Oracle/Sql?

六月ゝ 毕业季﹏ 提交于 2019-12-06 16:09:52

A couple of comments on the DDL you posted.

  • There is no AUTOINCREMENT keyword in Oracle. You'd need to create a sequence (generally one sequence per table) and use the NEXTVAL from the sequence either in the INSERT statement itself or in a trigger to populate the synthetic primary key.
  • There is nothing that is creating a VENUE_NO column in EVENT_DETAILS. I assume your actual DDL is defining that column.

You cannot enforce this through a simple CHECK constraint. You can create a trigger

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;

Be aware, however, that

  • You would also need to have a trigger on the VENUE table that checks to see whether changes to the venue's capacity causes certain events to become invalid. Generally, that would require that there is some sort of date in the event details table since, presumably, the capacity of a venue can change over time and you really only want the validation to check for future events in that venue.
  • Trigger based solutions will not always work in multi-user environments. Imagine venue 1 has a capacity of 30. Now, session A updates that capacity to 15. But before session A commits, session B inserts an event with a NO_PLAYERS of 20. Neither session's trigger will see a problem so both changes will be allowed. But once both sessions commit, there will be an event booked with 20 players in a venue that only supports 15 players. The trigger on EVENT_DETAILS could potentially lock the row in the VENUE table to avoid this race condition but they you're serializing inserts and updates on the EVENT_DETAILS table which could be a performance problem particularly if your application ever waits for human input before committing a transaction.

As an alternative to triggers, you can create an ON COMMIT materialized view that joins the two tables together and put a CHECK constraint on that materialized view that enforces the requirement that the number of players cannot exceed the venue capacity. That will work in a multi-user environment but it requires materialized view logs on both base tables and it moves the check to the point where the sessions commit which can be a bit tricky. Most applications don't consider the possibility that a COMMIT statement could fail so handling those exceptions can be tricky. And from a user-interface standpoint, it can be somewhat tricky to explain to the user what the problem is since the exception may relate to changes made much earlier in the transaction.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!