Question

I have a table 'Student', and several attributes - two of which are important in this particular problem. I need to make sure that any student with the classification (grade level) of 'junior' has between exactly 55 and 84 hours (credits).

Here's what I have have so far declaration-wise in Oracle (deleted unnecessary code):

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 throws the error:

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

I am certain that I haven't formatted the constraint correctly, but my professor spent about 3 seconds on declarations and told us to figure it out for ourselves. I know 1-attribute constraints, but I don't know how to mix and match 2 attributes at the same time. Can someone help me out?

*Essentially in any other code it would look like nested if-statements:

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

I just can't seem to translate that into SQL. My apologies if the spacing in this darn thing is bizarre, I can't get it to format to save my life.

Was it helpful?

Solution

You have a trailing comma right at the end, and one too many closing brackets:

...84))),);

Unless you've cut something out before posting, which may be the case as the error references line 23 (but hopefully not as it's tricky to see a problem in code you can't see at all). What you have compiles if that becomes:

...84)));

But the condition is wrong anyway, as others have pointed out. One way of getting the result I think you want is:

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

The OR means that the hours check is only applied when the classification is 'junior', and any other classification is not restricted. (If you need different rules for different classifications, have a look at the very similar question Chris Saxon linked to in comments).

With some test data:

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 is inclusive, so this is the same as:

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

You might also want a check constraint on classification, particularly as this constraint is case-sensitive as it stands; or preferably have a separate classification table and have a foreign key constraint on the column in this table. But that's probably out of your control for this assignment.

OTHER TIPS

Could it be that hours is allowed Null and that CHECK can't process field that allows Nulls..

So try making hours integer Not NULL and give a default value if your deem..

Also your condition has a mismatch.. check on that too....

Seems like the logic in your constraint might be off. Hours could never be less than 55 and greater than 84. Try using OR:

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

However, this doesn't ensure that when classification = 'junior' the hours are between 55 and 84. Try using this instead:

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

Good luck.

If you want to check that 'junior' should have value between 55 to 84 then use below compilable code-

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))) ;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top