Oracle 2属性CHECK约束问题

时间:2013-02-04 05:45:53

标签: sql oracle constraints check-constraints

我有一个表'学生'和几个属性 - 其中两个在这个特定问题中很重要。我需要确保任何分类(年级)为“初级”的学生在55到84小时之间(学分)。

以下是我迄今为止在Oracle中声明的内容(删除了不必要的代码):

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))),  
);

Oracle抛出错误:

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。我很抱歉,如果这件事中的间距很奇怪,我就无法将其格式化以挽救我的生命。

4 个答案:

答案 0 :(得分:1)

最后有一个尾随逗号,而且有一个太多的右括号:

...84))),);

除非您在发布之前删除了某些内容,否则可能就是错误引用第23行(但希望不会因为在代码中看到问题而难以查看)。如果变成了那么你编译的是什么:

...84)));

但正如其他人所指出的那样,这种情况无论如何都是错误的。获得我认为你想要的结果的一种方法是:

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

OR表示只有在hoursclassification时才会应用'junior'检查,并且不限制任何其他classification。 (如果您需要针对不同分类的不同规则,请查看评论中链接的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表,并在该表的列上有一个外键约束。但这可能超出了你对这项任务的控制。

答案 1 :(得分:0)

可能是hours被允许NullCHECK无法处理允许Null的字段..

所以尝试制作hours integer Not NULL并提供默认值,如果您认为..

你的病情也不匹配..检查一下......

答案 2 :(得分: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))
祝你好运。

答案 3 :(得分:0)

如果您想检查'junior'的值应介于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))) ;