2013-02-04 52 views
1

我有一個'Student'表和幾個屬性 - 其中兩個對於這個特定問題很重要。我需要確保任何分類(年級)爲'初級'的學生在55到84小時(學分)之間。Oracle 2屬性CHECK約束問題

這裏是我到目前爲止在甲骨文(刪除不必要的代碼)的聲明明智:

CREATE TABLE Students ( 
id INTEGER, 
name CHAR(10) NOT NULL, 
classification CHAR(10) NOT NULL, 
hours INTEGER, 
gpa NUMBER(3,2) NOT NULL, 
mentor INTEGER, 
-- IC4: 
-- To be classified as a 'junior', a student must have 
-- completed between 55 and 84 hours (inclusive). 
CONSTRAINT IC4 CHECK (classification != 'junior' AND (hours < 55 AND hours > 84))), 
); 

甲骨文引發錯誤:

 
ERROR at line 23: 
ORA-00922: missing or invalid option 

我相信,我有沒有格式化這個限制是正確的,但是我的教授花了大約3秒鐘的時間申報,並告訴我們自己弄明白。我知道1屬性約束,但我不知道如何同時混合和匹配2個屬性。有人可以幫我嗎?

*基本上在任何其他代碼會看起來像嵌套的if語句:

if (classification == "junior") { 
    if (hours < 55 && hours > 84) 
     throwSomeError("Foolish!"); 
} 

我只是似乎無法翻譯成SQL。我很抱歉,如果這件事情的間隔是奇怪的,我不能得到它來保存我的生活格式。

+2

小時如何小於55且大於84? – sgeddes

+0

@sgeddes可能是一個答案;) – bonCodigo

+1

這看起來像[本]的副本(http://stackoverflow.com/questions/14669174/oracle-check-integrity-constraint/14669589#14669589) –

回答

1

您有尾隨逗號就在年底,和一個太多閉幕括號:

...84))),); 

除非你在發佈前切出來的東西,這可能是這種情況作爲錯誤引用第23行(但是希望不是,因爲它是棘手的看到在代碼中的一個問題,你不能看到在所有)。如果變成你有什麼編譯:

...84))); 

但條件是錯誤的,無論如何,正如其他人指出。你想要得到的結果,我認爲的一種方法是:

... 
CONSTRAINT IC4 CHECK (classification != 'junior' OR hours BETWEEN 55 AND 84) 
); 

OR意味着當classification'junior',和任何其他classification不受限制的hours檢查僅適用。 (如果您需要針對不同分類的不同規則,請查看the very similar question Chris Saxon鏈接到評論中)。

隨着一些測試數據:

insert into students values (1, 'A', 'junior', 54, 1, 1); -- ORA-02290 
insert into students values (2, 'B', 'junior', 55, 1, 1); -- OK 
insert into students values (3, 'C', 'junior', 84, 1, 1); -- OK 
insert into students values (4, 'D', 'junior', 85, 1, 1); -- ORA-02290 

insert into students values (5, 'E', 'senior', 54, 1, 1); -- OK 
insert into students values (6, 'F', 'senior', 55, 1, 1); -- OK 
insert into students values (7, 'G', 'senior', 84, 1, 1); -- OK 
insert into students values (8, 'H', 'senior', 85, 1, 1); -- OK 

select * from students order by id; 

    ID NAME  CLASSIFICATION HOURS GPA MENTOR 
---- ---------- -------------- ----- --- ------ 
    2 B   junior   55 1.00  1 
    3 C   junior   84 1.00  1 
    5 E   senior   54 1.00  1 
    6 F   senior   55 1.00  1 
    7 G   senior   84 1.00  1 
    8 H   senior   85 1.00  1 

6 rows selected 

BETWEEN是包容性的,所以這是一樣的:

CONSTRAINT IC4 CHECK (classification != 'junior' OR (hours >= 55 AND hours <= 84)) 

您還可能希望在classification檢查約束,特別是因爲這種約束的情況下現在敏感;或者最好有一個單獨的classification表,並對此表中的列有一個外鍵約束。但這可能超出了你對這項任務的控制。

+0

謝謝大家你的迴應!巧合的是,我的一位同學在昨天晚上的同一時間提出了完全相同的問題......怪異的呃? 但無論如何,除了我的約束是屁股後退(哎呦),我還有其他一些錯誤,由於其他代碼(如尾隨逗號),這是拋出甲骨文。 現在就工作,非常感謝紳士:) –

0

難道hours允許NullCHECK無法處理場,使Null秒。

所以儘量使hours integer Not NULL,如果你給1062的默認值..

而且你條件有一個不匹配..檢查也...

0

似乎在您的約束邏輯可能會關閉。時間永遠是小於55和大於84嘗試使用OR:

CONSTRAINT IC4 CHECK (classification != 'junior' AND (hours < 55 OR hours > 84)) 

然而,這並不能保證在分類=「初級」的時間使用這個,而不是55,並嘗試84之間是:

CONSTRAINT IC4 CHECK (classification = 'junior' AND hours >= 55 AND hours <= 84)) 

祝你好運。

0

如果你想檢查「初級」應該有55至84的值,然後使用下面編譯代碼 -

CREATE TABLE Students 
(id INTEGER, 
name CHAR(10) NOT NULL, 
classification CHAR(10) NOT NULL, 
hours INTEGER, gpa NUMBER(3,2) NOT NULL, 
mentor INTEGER, -- IC4: 
-- To be classified as a 'junior', 
a student must have -- completed between 55 and 84 hours (inclusive). 
CONSTRAINT IC4 CHECK (classification = 'junior' AND (hours >= 55 AND hours <= 84))) ;