2017-01-06 8 views
0

私はクラスを学生に登録するPostgresのデータベースを作っています。学生がクラスを持っているかどうかを確認するためのトリガ機能

コースに登録したい学生が、以前に登録したその時間に他のコースを持っていない場合、機能チェックの作成に就きません。

CREATE TABLE "semester" (
    "semester_id" serial primary key, 
    "semester_describtion" varchar); 

CREATE TABLE "course" (
    "c_id" serial not null, 
    "c_name" varchar NOT NULL, 
    "c_describtion" varchar, 
    "semester_id" int, 
    "startDate" DATE, 
    "endDate" DATE, 
    PRIMARY KEY (c_id, semester_id), 
    FOREIGN KEY (semester_id) references semester(semester_id)); 

CREATE TABLE "staff" (
    "staff_id" serial primary key, 
    "staff_lastname" varchar(40) NOT NULL, 
    "staff_firstname" varchar(40) NOT NULL, 
    "staff_email" varchar(40)); 

CREATE TABLE "student" (
    "s_id" serial PRIMARY KEY, 
    "s_lastname" varchar(40) NOT NULL, 
    "s_firstname" varchar(40) NOT NULL, 
    "semester_id" int default '1', 
    foreign key (semester_id) references semester(semester_id)); 

CREATE TABLE "location" (
    "location_id" serial, 
    "room_nr" int, 
    "building_id" varchar(40) DEFAULT 'D5', 
    "max_students" int default '10', 
    primary key (location_id, max_students)); 

CREATE TABLE "course_section" (
    "c_section_id" serial, 
    "c_id" int NOT NULL, 
    "semester_id" int NOT NULL, 
    "staff_id" int, 
    "location_id" int not null, 
    "c_section_date" DATE, 
    "c_section_time" TIME default '08:00', 
    "c_section_during" TIME default '01:30', 
    "c_section_type" TEXT not null, 
    "max_students" int default '10', 
    "students" int default '0', 
    check(c_section_type = 'L' OR c_section_type = 'W' 
     OR c_section_type = 'C' OR c_section_type = 'I'), 
    primary key (c_id, staff_id, location_id,c_section_date,c_section_time), 
    foreign key (c_id, semester_id) references course(c_id, semester_id), 
    foreign key (staff_id) references staff(staff_id), 
    foreign key (location_id, max_students) references location(location_id, max_students) 
    ); 

CREATE TABLE "enrollment" (
    "s_id" int not null, 
    "mark" int, 
    "c_id" int not null, 
    "semester_id" int not null, 
    primary key (s_id,c_id,semester_id), 
    foreign key (s_id) references student(s_id), 
    foreign key (c_id, semester_id) references course(c_id, semester_id)); 

トリガ機能とトリガ:

create function check_date() returns trigger as ' 
declare 
date1 date; 
time1 time; 
begin 

Select c_section_date, c_section_time into date1, time1 from enrollment e 
inner join course c using (c_id) 
inner join course_section cs using (c_id); 

IF EXISTS (select e.s_id , cs.c_section_date, cs.c_section_time from enrollment e 
inner join course c using (c_id) 
inner join course_section cs using (c_id) 
where new.s_id=e.s_id AND date1=c_section_date and time1 = c_section_time) THEN 
RAISE NOTICE ''You have classess on that time''; 
Return null; 
ELSE 
return new; 
END IF; 
END; 
' language 'plpgsql'; 

create trigger t_check_date before insert on enrollment for each row execute procedure check_date(); 

問題はそれだけで1クラスの学生を登録することが可能である

は、6つのテーブルがあります。 2番目のコースにenrollmentに挿入したい場合は、時間が異なってもRAISE NOTICEが表示されます。

+0

関数内の最初の 'SELECT'には、WHERE句がありません。意味はないようです。 –

答えて

0

あなたの機能は次のように動作します:

CREATE OR REPLACE FUNCTION check_date() 
    RETURNS trigger AS 
$func$ 
BEGIN 
    IF EXISTS (
     SELECT 1 
     FROM course_section cs1 
     WHERE cs1.c_id  = NEW.c_id 
     AND cs1.semester_id = NEW.semester_id 
     AND EXISTS (
     SELECT 1 
     FROM enrollment e 
     JOIN course_section cs USING (c_id, semester_id) 
     WHERE e.semester_id  = NEW.semester_id 
     AND e.s_id    = NEW.s_id 
     AND cs.c_section_date = cs1.c_section_date 
     AND cs.c_section_time = cs1.c_section_time)) THEN 

     RAISE NOTICE 'You have classes at that time'; 
     RETURN null; 
    END IF; 

    RETURN NEW; 
END 
$func$ LANGUAGE plpgsql; 

テーブルcourseは、我々は我々の目的のために省略することができるだけの足がかりです。 enrollmentおよびcourse_sectionは、(c_id, semester_id)に直接結合できます。

実際にはの日付よりの時刻が以上であることを確認する必要があります。 と重複するコースの時間範囲を確認する必要があります。

+0

それを調べていただきありがとうございますが、あなたの機能は私と同じように機能することが判明しました。私は同じ問題があることを意味し、1つのコースに1人の学生だけを入れることができます。 登録テーブルに日時を追加し、course_sectionごとに生徒を登録しました。それは私が達成したいと思っていたものから遠いですが、今のところうまくいきます – mvcias

関連する問題