Reputation: 23
This is my first time posting on Stack Overflow. I normally just search previous questions and find my answers but in this instance I can't seem to find the answer to my question either here or on the wider internet.
The issue I have is that I want to populate a many-to-many link table used for storing attendance automatically. When a new student is added to a course, the students StudentNo and each applicable Lesson's LessonNo will be entered into the link table as primary keys. In addition, the student's attendance code will automatically be set to 'T' to show that the attendance is To Be Confirmed.
I don't want this to be a procedure as the database expects upwards of 6,000 active studentNo entries, with over a hundred lessons being applicable to each student. Only home students (their definition, not mine) attend the college. The homeStudent primary key is identical to the overall student primary key.
My trigger is as follows:
CREATE OR REPLACE TRIGGER Student_Added_to_Course
AFTER INSERT ON HomeStudent
FOR EACH ROW
DECLARE
CURSOR applicable_lessons
IS
Select Student.studentNo, Lesson.LessonNo
FROM
Student, Lesson, Course, Module
WHERE
Student.StudentNo = :new.studentNo
AND
Student.CourseNo = Course.CourseNo
AND
Course.CourseNo = Module.CourseNo
AND
Lesson.ModuleNo = Module.ModuleNo;
BEGIN
FOR I IN applicable_lessons
LOOP
INSERT INTO Attendance (StudentNo, LessonNo, AttendanceCode)
VALUES (I.student.studentNo, I.Lesson.LessonNo, 'T');
END LOOP;
END;
/
I am receiving the following errors:
Line 18: SQL statement ignored Line 19: component 'Lesson' must be declared Line 19: column not allowed here
Since all my errors are occurring from line 18 onwards I assume I have made a mistake during my insertion loop?
Could anybody tell me what I'm doing wrong here. I assume the fix is fairly straightforward but I'm at the point of going a bit cross-eyed looking at my own work and can't find the fault.
Thank you in advance, Bobrek
Upvotes: 2
Views: 43
Reputation: 23588
Why loop over a cursor when you can just do a single insert statement? That will be faster!
E.g.:
CREATE OR REPLACE TRIGGER Student_Added_to_Course
AFTER INSERT ON HomeStudent
FOR EACH ROW
BEGIN
INSERT INTO attendance (studentno, lessonno, attendancecode)
SELECT s.studentno,
l.lessonno,
'T'
FROM student s
INNER JOIN course c ON s.courseno = c.courseno
INNER JOIN module m ON c.courseno = m.courseno
INNER JOIN lesson l ON m.moduleno = l.moduleno
WHERE s.studentno = :new.studentno;
END Student_Added_to_Course;
/
Note that I have changed your join syntax to use ANSI join syntax, and note how it's much easier to see how the tables are linked.
Upvotes: 0
Reputation: 143053
If you change INSERT
statement to
INSERT INTO Attendance (StudentNo, LessonNo, AttendanceCode)
VALUES (I.studentNo, I.LessonNo, 'T');
you should be good.
Because, cursor variable is i
and cursor selects studentno
and lessonno
columns; it doesn't matter (any more) which table they belong to - you reference them by cursor variable's name, i.e. i.studentno
and i.lesonno
.
Upvotes: 1