Есть один хак, который вы можете сделать, но я сомневаюсь, что производительность вставки игр или событий будет приемлемой, когда таблицы увеличатся до определенного размера:
CREATE TABLE Event
(
IDEvent NUMBER(8) PRIMARY KEY,
StartDate DATE NOT NULL,
EndDate DATE NOT NULL
);
CREATE TABLE Game
(
IDGame NUMBER(8) PRIMARY KEY,
GameDate DATE NOT NULL,
eventid NUMBER(8), -- this is different to your table definition
CONSTRAINT fk_game_event FOREIGN KEY (eventid) REFERENCES event (idevent)
);
CREATE INDEX game_eventid ON game (eventid);
CREATE MATERIALIZED VIEW LOG ON event
WITH ROWID, SEQUENCE (idevent, startdate) INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW LOG ON game
WITH ROWID, SEQUENCE (idgame, eventid, gamedate) INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW mv_event_game
REFRESH FAST ON COMMIT WITH ROWID
AS
SELECT ev.idevent,
ev.startdate,
g.gamedate
FROM event ev, game g
WHERE g.eventid = ev.idevent;
ALTER TABLE mv_event_game
ADD CONSTRAINT check_game_start check (gamedate >= startdate);
Теперь любая транзакция, которая вставляетигра, которая запускается до того, как упомянутое событие вызовет ошибку при попытке совершить транзакцию:
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning and OLAP options
SQL> INSERT INTO event
2 (idevent, startdate, enddate)
3 values
4 (1, date '2012-01-22', date '2012-01-24');
1 row created.
SQL>
SQL> INSERT INTO game
2 (idgame, eventid, gamedate)
3 VALUES
4 (1, 1, date '2012-01-01');
1 row created.
SQL> commit;
commit
*
ERROR at line 1:
ORA-12008: error in materialized view refresh path
ORA-02290: check constraint (FOOBAR.CHECK_GAME_START) violated
Но опять же: это сделает медленной вставкой в обе таблицытак как запрос внутри mview должен выполняться каждый раз, когда выполняется коммит.
Мне не удалось изменить тип обновления на FAST
, что, вероятно, улучшило бы производительность фиксации.