Question

I have a table of STUDENTS which contains student information. Each student might or might not be a CANDIDATE in a college voting event, depending on the value of CANDIDATE BIT.

I'd like to have a table VOTE which keeps the votes of students, but I'd like to check if the student which is being inserted as VOTES_FOR is actually a CANDIDATE or not. In plain english: Check if the person being voted for is actually a candidate or not.

Any idea on how I can check for this constraint? I want to do this task using simple regular DDL commands not stored procedure and PL/SQL or T-SQL

CREATE TABLE STUDENTS(
    ID INT NOT NULL UNIQUE AUTO_INCREMENT = 1,
    FIRST_NAME NVARCHAR(20) NOT NULL ,
    LAST_NAME NVARCHAR(20) NOT NULL,
    CANDIDATE BIT DEFAULT '0',
    PRIMARY KEY(ID)
);    
CREATE TABLE VOTE(
    STUDENT_ID references STUDENTS(ID),
    VOTES_FOR references STUDENTS(ID),
    PRIMARY KEY STUDENT_ID
);
Was it helpful?

Solution

Declare a UNIQUE constraint on the pair of columns "ID" and "CANDIDATE", and reference that pair from the table "VOTES". Use a CHECK constraint in "VOTES" to guarantee that votes are recorded only for a candidate.

CREATE TABLE STUDENTS(
    ID INTEGER PRIMARY KEY,
    FIRST_NAME VARCHAR2(20) NOT NULL,
    LAST_NAME VARCHAR2(20) NOT NULL,
    CANDIDATE CHAR(1) DEFAULT 'f' NOT NULL 
      CHECK (CANDIDATE IN ('t', 'f')),
    UNIQUE (ID, CANDIDATE)
);

CREATE TABLE VOTES(
    STUDENT_ID INTEGER PRIMARY KEY
      REFERENCES STUDENTS (ID),
    VOTES_FOR INTEGER NOT NULL,
    CANDIDATE CHAR(1) DEFAULT 't' 
      CHECK (CANDIDATE = 't'),
    FOREIGN KEY (VOTES_FOR, CANDIDATE)
      REFERENCES STUDENTS (ID, CANDIDATE)
);

"IS_CANDIDATE" is probably a better name than "CANDIDATE"; "CANDIDATE_ID" is probably a better name than "VOTES_FOR".

OTHER TIPS

Right on for seeking a DDL solution for this type of problem.

I'd push towards incorporating a Candidate table. My reasoning is this will allow you to declare unique traits such as start and end candidacy times that would enable a student to try to become a candidate the following year or later.

Also this gives you an ID for that candidate to refer to.

CREATE TABLE student {
    id INTEGER PRIMARY KEY,
    fname VARCHAR(20) NOT NULL,
    lname VARCHAR(20) NOT NULL
};

CREATE TABLE candidate {
    id INTEGER PRIMARY KEY,
    student_id INTEGER(11) NOT NULL,
    start_year INTEGER(4) NOT NULL,
    start_month INTEGER(2) NOT NULL,
    start_day INTEGER(2) NOT NULL,
    end_year INTEGER(4) NULL,
    end_month INTEGER(2) NULL,
    end_day INTEGER(2) NULL
}

CREATE TABLE vote {
    student_id INTEGER(11) NOT NULL,
    candidate_id INTEGER(11) NOT NULL
};

If you're using Oracle and the database you want to look into a Ref Constraint here's an exmample Ref Constraint Example

Although the situation may be a little more complex than Oracle constraints allow for. This article written by Tony Andrews provides an ingenious workaround for achieving your desired results.

Have you tried using the SQL CHECK constraint?

http://www.w3schools.com/sql/sql_check.asp

You're going to need a composite foreign key to provide the check you want.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top