2012-01-22 23 views
0

私がやりたいことは簡単で、以下は詳細です。私は2つのテーブルを持っています。Oracle Sqlのチェック制約

Create Table Event(
IDEvent number (8) primary key, 
StartDate date not null, 
EndDate date not null 
); 

これは問題ありません。

ここは2番目の表です。

Create Table Game(
IDGame number (8) primary key, 
GameDate date not null, 
constraint checkDate 
check (GameDate >= to_date(StartDate references from Event(StartDate))) 
); 

制約チェックデートは、日付が開始日よりも大きいかどうかをチェックすることです。チェックしているうちにエラーが発生しています:Missing right parenthesis

私の質問は、これができれば、なぜ私にエラーが出るのですか?

+1

「イベント」に「StartDate」という5つのレコードがある場合、「GameDate」と比較したいですか? –

答えて

4

表のチェック制約は、その特定の表の列の条件のみを検証できます。他のテーブルの列は参照できません。

異なる表の列を含む条件を検証する必要がある場合は、その表の挿入/更新トリガーの前に実行できます。

+0

ええええええええええええええええええん – P3druh77

0

あなたがしたいことは簡単ではありません。

提案する構文は、どのRDBMSでも機能しません。このようなクロステーブルの整合性ルールを実施すると、参照テーブルをロックしてゲームテーブルを更新するため、RDBMSベンダが実装していない方がいいでしょう。それを自分で構築しようとすると、自分でロックを行う必要があります。

  • 以上にイベントSTARTDATEを更新
  • 少ない最近の日付にゲームgamedateを更新
  • を挿入:あなたのような可能性があなたのルールに違反する可能性があり、すべてのアクションは、考慮に入れる必要があるでしょう最近の日付
  • イベント

を削除し、これらのアクションのそれぞれについて、あなたは他のテーブルで右のレコードをロックすることにより、マルチユーザー証明されたコードを書くことを考える必要があります。

あなたはこの複雑さを軽減したい場合は、RuleGenと呼ばれる製品で見たいと思うかもしれません(www.rulegen.com)

それとも、特定のAPIを構築したいとちょうどでチェックを含むことができ場所。このシナリオでは、手動でロックする必要があります。

これが役に立ちます。

よろしくお願いします。
Rob。

0

あり、あなたが作ることができる1つのハックですが、私はテーブルが一定の大きさに成長一度、許容されるもので挿入ゲームやイベントの性能を疑う:ゲームを挿入今

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に変更できませんでした。おそらくコミットのパフォーマンスが向上します。

+0

真実これは実現可能なパフォーマンスではありません。また、同時更新中にいくつかの追加の競合が発生します(http://rwijk.blogspot.com/2010/01/enq- jou-contention.html)。ROWIDを結合mvに追加すると、マテリアライズド・ビューが高速にリフレッシュされることに注意してください。 –

+0

@RobvanWijk:高速リフレッシュに関するヒントをありがとう。私の試行のうちの1つのROWID(しかし、ログだけだったかもしれない) –

関連する問題