Reputation: 13
I am working on a project for Uni and I don't have much knowledge or experience with databases. I am trying to create a database in Oracle with a table that contains manufactured parts that can be of 2 types, say 1 and 2. When the part is of type 1 I will store in the table its location, when it's of type 2 I will store in the same table the lead time. Thus I will have null values for the other column in both cases (I am aware of the issues with the null values, but after thinking about it and researching what is the best way of dealing with this, I decided to do it like this, as I have only a small amount of atributes). My problem is in the CHECK CONSTRAINT. I tried to do it this way:
CREATE TABLE manufactured (
PID INT NOT NULL,
PARTTYPE NUMBER (1) NOT NULL,
CHECK (PARTTYPE IN (1,2)),
CONSTRAINT REFMAN FOREIGN KEY (PID, PARTTYPE) REFERENCES PART (PID, PARTTYPE),
LOCATION VARCHAR (50),
CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL),
CONSTRAINT LOC2 CHECK(PARTTYPE=2 AND LOCATION IS NULL),
LEAD_TIME VARCHAR (50),
CONSTRAINT LEADTIME CHECK (PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
CONSTRAINT LEADTIME2 CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL),
CONSTRAINT PK_MAN PRIMARY KEY (PID));
This is not working.
I tried to insert a record as follows:
insert into manufactured(PID, PARTTYPE, LOCATION) values(101,1,'Warehouse1');
And I get the error: ORA-02290: check constraint (*****.LEADTIME) violated
I also tried:
insert into manufactured values (101,1,'Warehouse1');
And I get the error:
ORA-00947: not enough values
And finally with this:
insert into manufactured(PID, PARTTYPE, LEAD_TIME) VALUES (102, 2, '2 WEEKS');
I get the following error: ORA-02290: check constraint (****.LEADTIME2) violated
Thank you in advance for your help.
Upvotes: 1
Views: 130
Reputation: 17934
This insert statement:
insert into manufactured(PID, PARTTYPE, LOCATION) values(101,1,'Warehouse1');
...fails because your LEADTIME
constraint requires that PARTTYPE=2
. (It's an AND
condition, so if PARTTYPE=1
the constraint will fail regardless of the value for LEAD_TIME
.)
This is what I think you are looking for:
CREATE TABLE manufactured (
PID INT NOT NULL,
PARTTYPE NUMBER (1) NOT NULL,
CHECK (PARTTYPE IN (1,2)),
CONSTRAINT REFMAN FOREIGN KEY (PID, PARTTYPE) REFERENCES PART (PID, PARTTYPE),
LOCATION VARCHAR (50),
--CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL),
--CONSTRAINT LOC2 CHECK(PARTTYPE=2 AND LOCATION IS NULL),
CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL OR PARTTYPE=2 AND LOCATION IS NULL),
LEAD_TIME VARCHAR (50),
--CONSTRAINT LEADTIME CHECK (PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
--CONSTRAINT LEADTIME2 CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL),
CONSTRAINT LEADTIME CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL OR PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
CONSTRAINT PK_MAN PRIMARY KEY (PID));
Basically, make one constraint on each column that enforces the whole set of logic for that column.
If you really want two constraints on each column, you can do that too. If so, post a comment and I'll update this answer. I don't want to clutter/confuse the issue otherwise.
Upvotes: 1
Reputation: 65278
The Error ORA-00947: not enough values
for
insert into manufactured values (101,1,'Warehouse1');
is obvious,
since the last column (lead_time
) of the table(manufactured
) is missing for the values
list.
The Errors ORA-02290: check constraint
stem from the dependent
conditions among the check constraints LEADTIME
and LEADTIME2
,
those should be combined as
CONSTRAINT LEADTIME CHECK ((PARTTYPE=2 AND LEAD_TIME IS NOT NULL) OR (PARTTYPE=1 AND LEAD_TIME IS NULL))
.
The same logic works also for constraints LOC
and LOC2
which should yield
CONSTRAINT LOC CHECK ((PARTTYPE=1 AND LOCATION IS NOT NULL) OR (PARTTYPE=2 AND LOCATION IS NULL))
Upvotes: 0
Reputation: 610
I don't know which RDBMS you use. For example in Oracle CHECK constraint accepts nulls.
As i see there are different attributes/datatypes for each party type. There are two approach:
Upvotes: 0