2013-02-04 42 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))) ;