我有两个表:
CREATE TABLE Event_details( event_no INTEGER AUTOINCREMENT NOT NULL, no_players INTEGER NOT NULL, game_type VARCHAR(20) NOT NULL, payout_positions INTEGER NOT NULL, PRIMARY KEY(event_no) CONSTRAINT check_game_type CHECK(game_type IN ('NLH','NLO','PLO','PLH','STUD','HORSE') CONSTRAINT check_no_players CHECK (no_players > 1) CONSTRAINT check_payouts CHECK (payout_positions > 0 AND payout_positions < no_players)); CREATE TABLE Venue( venue_no INTEGER AUTOINCREMENT NOT NULL, name VARCHAR(20) NOT NULL, location VARCHAR(20) NOT NULL, capacity INTEGER NOT NULL, PRIMARY KEY (venue_no) CONSTRAINT check_capacity CHECK (capacity > 0));
以及它们之间的外键:
ALTER TABLE Event_details ADD FOREIGN KEY (venue_no) REFERENCES Venue(venue_no) ON DELETE SET NULL;
我想设置一个CONSTRAINT(或TRIGGER ???),该条目将不允许(或标记)Event_details(no_players)<Venue(capacity)其中Venue(capacity)是在外键行中找到的值的条目。
这可能吗?
关于您发布的DDL的一些评论。
AUTOINCREMENT
NEXTVAL
INSERT
VENUE_NO
EVENT_DETAILS
您不能通过简单的CHECK约束来强制执行此操作。您可以创建一个触发器
CHECK
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;
但是请注意,
VENUE
NO_PLAYERS
作为触发器的替代方法,您可以创建ON COMMIT将两个表连接在一起的CHECK实例化视图,并对该实例化视图施加约束,以强制要求玩家人数不能超过场地容量。这将在多用户环境中工作,但是它需要两个基表上的物化视图日志,并将检查移到会话提交的位置,这可能会有些棘手。大多数应用程序不考虑COMMIT语句可能失败的可能性,因此处理这些异常可能很棘手。并且从用户界面的角度来看,向用户解释问题是有些棘手的,因为异常可能与事务中更早进行的更改有关。
ON COMMIT
COMMIT