Điều này đặt ra vấn đề cho việc quản lý hệ thống các trung tâm ngoại ngữ ấy, làm sao để hệ thống có thể hoạt động một cách hiệu quả cũng như có giúp việc quản lý học viên, giảng viên tro
Trang 1ĐẠI HỌC QUỐC GIA TP.HCM
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
KHOA HỆ THỐNG THÔNG TIN
ĐỒ ÁN MÔN HỌC
HỆ QUẢN TRỊ CƠ SỞ DỮ LIỆU
ĐỀ TÀI: QUẢN LÝ TRUNG TÂM TIẾNG ANH
Giáo viên hướng dẫn: Nguyễn Hồ Duy Tri
Sinh viên thực hiện:
Võ Ngọc Lệ Xuân – 21521692
Lê Thị Thanh Hằng – 21520222 Trần Kim Thanh – 21522605 Ngô Tất Tố – 21520484
TP.HCM, tháng 6 năm 2023
Trang 2LỜI CẢM ƠN
Đầu tiên, nhóm tác giả xin gửi lời cảm ơn chân thành đến tập thể quý Thầy Cô Trường Đại học Công nghệ thông tin – Đại học Quốc gia TP.HCM và quý Thầy Cô khoa Hệ thống thông tin đã giúp cho nhóm tác giả có những kiến thức cơ bản làm nền tảng để thực hiện đề tài này
Đặc biệt, nhóm tác giả xin gửi lời cảm ơn và lòng biết ơn sâu sắc nhất tới thầy Nguyễn Hồ Duy Tri (Giảng viên hướng dẫn thực hành môn Hệ quản trị Cơ sở dữ liệu) Thầy đã trực tiếp hướng dẫn tận tình, sửa chữa và đóng góp nhiều ý kiến quý báu giúp nhóm tác giả hoàn thành tốt báo cáo môn học của mình
Trong thời gian một học kỳ thực hiện đề tài, nhóm tác giả đã vận dụng những kiến thức nền tảng đã tích lũy đồng thời kết hợp với việc học hỏi và nghiên cứu những kiến thức mới Từ đó, nhóm tác giả vận dụng tối đa những gì đã thu thập được để hoàn thành một báo cáo đồ án tốt nhất Tuy nhiên, trong quá trình thực hiện, nhóm tác giả không tránh khỏi những thiếu sót Chính vì vậy, nhóm tác giả rất mong nhận được những sự góp ý từ phía Thầy nhằm hoàn thiện những kiến thức mà nhóm tác giả đã học tập và là hành trang để nhóm tác giả thực hiện tiếp các đề tài khác trong tương lai
Trang 33 Thiết kế mô hình quan hệ, bảng thuyết minh quan hệ và thuộc tính, mô tả ràng buộc
3.3 Bảng thuyết minh quan hệ và thuộc tính 10
1.2 Mô tả các trigger trong đồ án môn học 26
2.2 Mô tả các procedure trong đồ án môn học 38
Trang 42.3 Giao tác đọc không thể lặp lại (Non-repeatable read) 62
1.Giới thiệu các tính năng của giao diện 69
1.11 Xem các khóa học trong trung tâm (Học viên) 90
1.13 Xem thông tin các khóa học đã và đang học của học viên (Học viên) 92
1.15 Xem thông tin khóa học (Giảng viên) 95 1.16 Quản lý điểm học viên (Giảng viên) 97 1.17 Xem thông tin chấm công (Giảng viên) 98
2 Môi trường phát triển và môi trường triển khai 102
Trang 52.1 Môi trường phát triển 102
Trang 6
Hệ thống quản lý trung tâm tiếng anh đang cần quản lý rất nhiều thông tin như: thông tin học viên, thông tin khóa học, thông tin giảng viên, ….và hệ thống cần được xây dựng dựa trên yêu cầu của người dùng, hỗ trợ lưu trữ và truy xuất thông tin một cách dễ dàng hơn, tránh rủi ro mất dữ liệu Hệ thống cần giải quyết được các vấn đề trên một cách nhanh chóng và tối ưu Đem lại một giao diện thân thiện cho người dùng, giúp học viên đăng ký học một cách dễ dàng hơn, hỗ trợ giảm thiểu các công việc cho người quản trị viên, nâng cao hiệu suất làm việc
Bên cạnh đó, hệ thống cũng phải giải quyết được các vấn đề sai sót dữ liệu xảy
ra do truy xuất đồng thời giữa các người dùng trong hệ thống, như việc đăng ký khóa học giữa các học viên, thêm và cập nhật thông tin giữa các quản trị viên Hơn nữa, hệ thống cũng cần hỗ trợ việc sao lưu và phục hồi dữ liệu một cách nhanh chóng và đáng tin cậy
Trang 7
Ngoài ra, hệ thống cũng cần phải có tính linh động để có thể chuyển sang các hệ thống khác liên quan khi cần như hệ thống quản lý trường học, quản lý trung tâm luyện thi, … để tiết kiệm chi phí và thời gian
1.2 Giải pháp
Để có thể giải quyết các vấn đề đưa ra, nhóm chúng em đề xuất giải pháp là xây dựng một ứng dụng hỗ trợ việc quản lý trung tâm với đầy đủ các chức năng để phục vụ cho các nghiệp vụ của trung tâm, tin học hóa các việc lưu trữ và truy xuất thông tin, giúp cho công việc kinh doanh của trung tâm trở nên thuận tiện, chuyên nghiệp hơn Học viên có thể đăng ký các khóa học, quản trị viên có thể đưa thông tin vào hệ thống một cách đồng thời nhưng vẫn chính xác, tránh các sự cố liên quan đến dữ liệu
Tất cả phần mềm được nhóm cài đặt trên hệ điều hành Windows 11
2 Xác định và phân tích yêu cầu
2.1 Phân tích yêu cầu
- Học viên: thêm, xóa, sửa, tra cứu học viên, xem thông tin các khóa học và
chương trình khuyến mãi đang được mở, xem được thông tin cá nhân và điểm số
- Giảng viên: thêm, xóa, sửa, tra cứu giảng viên, hỗ trợ giảng viên nhập điểm cho sinh viên, chấm công, xem thông tin cá nhân của giảng viên và tính lương cho giảng viên đó
- Chấm công: thêm, xóa, sửa, tra cứu thời gian giảng viên chấm công và dựa vào
đó để tính lương cho giảng viên
Trang 8- Lịch dạy: thêm, xóa, sửa, tra cứu một lịch giảng dạy, hỗ trợ giảng viên biết được mình đang phụ trách khóa học nào
- Khóa học: thêm, xóa, sửa, tra cứu các khóa học hiện đang được mở tại trung tâm
và lưu trữ thông tin các khóa học đã kết thúc Một khóa học được mở có thể cho nhiều học viên đăng ký và học viên cũng có thể đăng ký nhiều khóa học
- Khuyến mãi: thêm, xóa, sửa, tra cứu các khuyến mãi đã diễn ra và lưu trữ thông tin các khuyến mãi đã hết hạn Một khuyến mãi được mở cho nhiều học viên áp dụng khi đăng ký khóa học, nhưng một học viên chỉ được áp dụng 1 khuyến mãi/1 khóa học
- Điểm số học viên: thêm, xóa, sửa và tra cứu điểm số của học viên Trong một khóa học, học viên có thể tham gia nhiều bài kiểm tra và hệ thống sẽ lưu lại thông tin bài kiểm tra đó thông qua giảng viên phụ trách
- Báo cáo: hỗ trợ báo cáo thống kê doanh thu theo ngày, tháng, năm
2.2 Yêu cầu chức năng
• Chức năng lưu trữ dữ liệu
- Tính năng lưu trữ được lưu trên hệ quản trị cơ sở dữ liệu Oracle, chứa các thông tin quan trọng, như thông tin học viên, giảng viên, chương trình khuyến mãi, rạp, nhân viên, … Giúp dễ dàng cho việc truy xuất dữ liệu
• Chức năng thống kê, tính toán
- Hỗ trợ tính lương cho giảng viên: tính toán và đưa ra lương tháng cho giảng viên dựa trên thông tin chấm công của họ trong tháng được lưu trữ trong hệ thống
- Hỗ trợ tính điểm trung bình cho học viên khi tham gia khóa học: hệ thống lấy thông tin các bài kiểm tra được thêm bởi giảng viên và tính toán đưa ra điểm trung bình
- Hỗ trợ báo cáo, thống kê: hệ thống tính toán, đưa ra các báo cáo thống kê dựa trên các khóa học được bán ra Các thống kê, báo cáo được đưa ra dựa theo từng tháng, hoặc từng năm
• Chức năng tìm kiếm, tra cứu:
- Nhân viên quản lý có thể thực hiện các chức năng tìm kiếm, tra cứu thông tin: Học viên, giảng viên, khóa học, lịch dạy,
• Chức năng xử lý đồng thời
- Khi một học viên đang đăng ký khóa học thì một học viên khác không được vào
Trang 9- Xử lý các vấn đề gây mất nhất quán dữ liệu lost update, uncommitted, deadlock,
phantom, dirty read
2.3 Yêu cầu phi chức năng
*Yêu cầu về chất lượng:
- Tính tiến hoá: dễ dàng nâng cấp, cập nhật hệ thống, có thể nâng cấp lên hệ thống quản lý trung tâm trên nền tảng online
- Tính hiệu quả: ứng dụng hoạt động tốt và đáng tin cậy
- Tính tiện dụng: dễ dàng sử dụng, tốc độ xử lý dữ liệu nhanh
- Tính tương thích: Hoạt động tốt trên các hệ điều hành phổ biến như Window, Linux
*Yêu cầu về giao diện:
- Gần gũi, thân thiện với người dùng
- Các thông tin cần thiết được hiển thị một cách rõ ràng, chi tiết
3 Thiết kế mô hình quan hệ, bảng thuyết minh quan hệ và thuộc tính, mô tả ràng buộc toàn vẹn
3.1 Mô hình ERD
Trang 10
3.2 Mô hình quan hệ
STUDENT(S_ID, S_NAME, S_PHONE, S_BIRTH, S_MAIL, S_LEVEL,
S_SEX, S_ADDR)
COURSE(C_ID, C_NAME, C_LEVEL, C_START, C_END, C_FEE)
RESULT(C_ID, S_ID, R_DATE, R_TEST, R_SCORE)
TEACHERSTAFF(T_ID, T_NAME, T_PHONE, T_BIRTH, T_STARTDATE ,T_MAIL, T_ICNUM, T_SALARY, T_SEX, T_ADDR, T_PORTION)
DISCOUNT(D_ID, D_NAME, D_PERCENTAGE, D_START, D_END)
JOIN_COURSE (S_ID, C_ID, D_ID, S_FEE, STATUS)
WORKING (W_ID, T_ID, W_HOURS, W_CHECKIN, W_CHECKOUT)
TEACHING (TE_ID, T_ID, C_ID)
ACCOUNT (A_MAIL, A_PASS, A_KIND, A_IMG)
ADMIN (Q_ID, Q_NAME, Q_PHONE,Q_BIRTH, Q_STARTDATE, Q_ICNUM, Q_SALARY, Q_MAIL, Q_SEX, Q_ADDR, Q_PORTION)
3.3 Bảng thuyết minh quan hệ và thuộc tính
3.3.1 Table: STUDENT
Thuộc tính Kiểu dữ liệu Ý nghĩa Ràng buộc
S_ID varchar2(10) Mã học viên Khóa chính
S_NAME nvarchar2(30) Tên học viên
S_PHONE varchar2(15) Số điện thoại
S_MAIL varchar2(40) Email
S_LEVEL varchar2(20) Trình độ học
viên
Trang 11
S_SEX nvarchar2(10) Giới tính
S_ADDR Nvarchar(100) Địa chỉ
3.3.2 Table: COURSE
Thuộc tính Kiểu dữ liệu Ý nghĩa Ràng buộc
C_ID varchar2(10) Mã khóa học Khóa chính
C_NAME varchar2(30) Tên khóa học
C_LEVEL varchar2(20) Cấp độ khóa
Trang 123.3.3 Table: RESULT
Thuộc tính Kiểu dữ liệu Ý nghĩa Ràng buộc
C_ID varchar2(10) Mã khóa học Khóa chính, khóa ngoại tham
chiếu đến khóa chính C_ID của bảng COURSE
S_ID varchar2(10) Mã học viên Khóa chính, khóa ngoại tham
chiếu đến khóa chính S_ID của bảng COURSE
R_DATE date Ngày kiểm tra Khóa chính
R_TEST varchar2(20) Loại bài kiểm
tra
Khóa chính
R_SCORE Number(4,2) Điểm
3.3.4 Table: JOIN_COURSE
Thuộc tính Kiểu dữ liệu Ý nghĩa Ràng buộc
S_ID varchar2(10) Mã học viên Khóa chính, khóa ngoại tham
chiếu đến khóa chính S_ID của bảng STUDENT
Trang 13C_ID varchar2(10) Mã khóa học Khóa chính, khóa ngoại tham
chiếu đến khóa chính C_ID của bảng COURSE
D_ID varchar2(10) Mã khuyến mãi Khóa ngoại tham chiếu đến
khóa chính D_ID của bảng DISCOUNT
S_FEE date Học phí sau khi
3.3.5 Table: TEACHERSTAFF
Thuộc tính Kiểu dữ liệu Ý nghĩa Ràng buộc
T_ID varchar2(15) Mã giảng viên Khóa chính
T_NAME nvarchar2(30) Tên giảng
viên
Not null
T_PHONE varchar2(200) Số điện thoại
T_STARTDATE date Ngày vào làm
T_MAIL varchar(40) Email
Trang 14T_ICNUM varchar(12) Số chứng
minh nhân dân
T_SALARY number(20) Lương cơ bản
T_SEX varchar(10) Giới tính
T_ADDR nvarchar(40) Địa chỉ
T_PORTION number(4,2) Hệ số lương
3.3.6 Table: WORKING
Thuộc tính Kiểu dữ liệu Ý nghĩa Ràng buộc
W_ID varchar2(10) Mã chấm công Khóa chính
T_ID date Mã nhân viên Khóa ngoại tham chiếu
đến khóa chính T_ID của bảng TEACHERSTAFF W_HOURS int
W_CHECKIN timestamp Thời gian
check-in
W_CHECKOUT timestamp Thời gian
check-out
Trang 15
3.3.7 Table: DISCOUNT
Thuộc tính Kiểu dữ liệu Ý nghĩa Ràng buộc
D_ID varchar2(10) Mã khuyến
3.3.8 Table: TEACHING
Thuộc tính Kiểu dữ liệu Ý nghĩa Ràng buộc
TE_ID varchar2(10) Mã lịch dạy Khóa chính
T_ID varchar2(20) Mã giảng viên Khóa ngoại tham chiếu đến
khóa chính T_ID của bảng TEACHERSTAFF
C_ID varchar2(20) Mã khóa học
Trang 163.3.9 Table: ADMIN
Thuộc tính Kiểu dữ liệu Ý nghĩa Ràng buộc
Q_ID varchar2(10) Mã quản trị
Q_PHONE Varchar2(20) Số điện thoại
Q_BIRTH Date Ngày sinh
Trang 17Q_SALARY number Lương cơ bản
Q_MAIL Varchar2(30) Email
Q_SEX Varchar2(20) Giới tính
Trang 18Thuộc tính Kiểu dữ liệu Ý nghĩa Ràng buộc
A_PASS varchar2(30) Mật khẩu
A_KIND varchar2(30) Loại tài khoản
A_IMG Varchar2(100) Đường dẫn ảnh chủ tài
khoản
3.4 Mô tả ràng buộc toàn vẹn
a R1: “Mã học viên của quan hệ học viên là duy nhất.”
Bối cảnh: STUDENT
RBTV liên bộ:
∀hv1, hv2 ∈ STUDENT: hv1.S_ID ≠ hv2.S_ID
b R2: “Mã giảng viên của quan hệ giảng viên là duy nhất.”
Bối cảnh: TEACHERSTAFF
RBTV liên bộ:
∀nv1, nv2 ∈ TEACHERSTAFF: nv1.T_ID ≠ nv2.T_ID
Trang 19c R3: “Mã khóa học của quan hệ khóa học là duy nhất.”
Bối cảnh: COURSE
RBTV liên bộ:
∀kh1, kh2 ∈ COURSE: kh1.C_ID ≠ kh2.C_ID
d R4: “Mã khuyến mãi của quan hệ khuyến mãi là duy nhất.”
Bối cảnh: DISCOUNT
RBTV liên bộ:
∀km1, km2 ∈ DISCOUNT: km1.D_ID ≠ km2.D_ID
e R5: “Mã quản trị viên của quan hệ quản trị viên là duy nhất.”
Bối cảnh: ADMIN
RBTV liên bộ:
∀ad1, ad2 ∈ ADMIN: ad1.Q_ID ≠ ad2.Q_ID
f R6: “Email của quan hệ tài khoản là duy nhất.”
Bối cảnh: ACCOUNT
Trang 20RBTV liên bộ:
∀ac1, ac2 ∈ ACCOUNT: ac1.A_MAIL ≠ ac2.A_MAIL
g R7: “Học viên không được đăng ký khóa học khác trình độ”
Bối cảnh: JOIN_COURSE, COURSE, STUDENT
RBTV liên quan hệ
∀ js ∈ JOIN_COURSE, s ∈ STUDENT, c ∈ COURSE => js.C_ID = c.C_ID ∧
js.S_ID = s.S_ID ∧ s.S_LEVEL = c.C_LEVEL
Trang 21R8 Thêm Xóa Sửa
i R9: “Ngày sinh của nhân viên phải nhỏ hơn ngày vào làm”
Bối cảnh: TEACHERSTAFF
RBTV liên thuộc tính
∀ te ∈ TEACHERSTAFF: te.T_START > te.T_BIRTH
l R11: “Ngày sinh của học viên nhỏ hơn ngày bắt đầu khóa học”
Bối cảnh: JOIN_COURSE, COURSE, STUDENT
RBTV liên quan hệ, liên thuộc tính
∀ te ∈ TEACHERSTAFF: te.T_START > teT_BIRTH
Trang 22R11 Thêm Xóa Sửa
∀ c ∈ COURSE: c.C_START < c.C_END
Trang 23R14 Thêm Xóa Sửa
p R15: “Sĩ số phải nhỏ hơn sức chứa của khóa học”
Bối cảnh: COURSE
RBTV liên thuộc tính
∀ c ∈ COURSE: c.C_CAPACITY > c.C_NUM
PHẦN 2: XÂY DỰNG VÀ QUẢN LÝ
GIAO TÁC 1.Trigger trong Oracle
*Định nghĩa: “Trigger là một thủ tục SQL được thực thi ở phía server khi có một
sự kiện như Insert, Delete, hay Update Trigger là một loại stored procedure đặc biệt (không có tham số) được thực thi (execute) một cách tự động khi có một sự kiện thay đổi dữ liệu (data modification)”
Theo https://topdev.vn/blog/trigger-trong-sql/
- Trong bất kỳ các hệ quản trị cơ sở dữ liệu nào cũng có 3 thao tác làm thay đổi dữ liệu chính đó là: INSERT, UPDATE, DELETE Và khi muốn thực thi một hành
động gì đó trước hoặc sau khi thực 3 thao đó xảy ra thì đó là TRIGGER
- Như vậy chúng ta có 2 nhóm trigger chính:
Trang 24Nhóm BEFORE Nhóm AFTER
TRIGGER
AFTER INSERT TRIGGER
TRIGGER
AFTER UPDATE TRIGGER
TRIGGER
AFTER DELETE TRIGGER
- Lưu ý: BEFORE TRIGGER không tạo cho view
- BEFORE TRIGGER: Là những thao tác hành động thực thi sau khi hành động chính hoàn thành (INSERT, UPDATE, DELETE)
- AFTER TRIGGER: Là những thao tác hành động thực thi trước khi hành động chính hoàn thành (INSERT, UPDATE, DELETE)
*Cú pháp khi viết trigger:
CREATE TRIGGER trigger_name trigger_time trigger_event
*Một số lưu ý khi viết trigger:
1) Trong TRIGGER không có SELECT mà chỉ có SELECT… INTO INSERT và UPDATE sử dụng :NEW.thuoc_tinh, DELETE sử dụng :OLD.thuoc_tinh Để lấy các
tên biến mới chén vào hoặc xóa đi để phục vụ cho các thao tác khác trong trigger
2) Để chạy được trigger trong ORACLE trước một câu trigger dùng thêm
SET DEFINE OFF;
3) TRIGGER trong ORACLE không được sử dụng các giao tác COMMIT, ROLLBACK
Nếu kiểm tra điều không thỏa thì:
raise_application_error (-20000, ‘Chuoi thong bao!’);
Trang 252 check_duplicate_working_dates Insert,
update
WORKING Không có hai
ngày chấm công trùng nhau
3 check_birth_before_start Insert TEACHERSTAFF Ngày sinh của
nhân viên phải nhỏ hơn ngày vào làm
6 check_birth_before_c_start_udt Update COURSE Ngày bắt đầu
không thể nhỏ hơn ngày sinh của các học viên trong khóa học
7 check_start_end Insert,
update
COURSE Ngày kết thúc
khóa học phải lớn hơn ngày bắt đầu
Trang 2610 check_class_capacity_ins Insert JOIN_COURSE Sĩ số không lớn
hơn sức chứa của một lớp
11 check_class_capacity_udt Update COURSE Sức chứa không
thể nhỏ hơn sĩ số hiện tại của khóa học
1.2 Mô tả các trigger trong đồ án môn học
1.2.1 Trigger trên bảng JOIN_COURSE
* Tên trigger: check_course_level
* Mô tả: Khi học viên đăng ký khóa học phải cùng trình độ
* Mã lệnh PL/SQL:
CREATE OR REPLACE TRIGGER check_course_level
BEFORE INSERT OR UPDATE ON JOIN_COURSE
FOR EACH ROW
Trang 27SELECT s_level INTO student_level FROM STUDENT WHERE s_id =
:NEW.s_id;
Lấy trình độ của khóa học
SELECT c_level INTO course_level FROM COURSE WHERE c_id =
:NEW.c_id;
Kiểm tra nếu trình độ của học viên và khóa học không khớp
IF student_level <> course_level THEN
RAISE_APPLICATION_ERROR(-20001, 'Học viên không thể đăng ký khóa học không khớp trình độ.');
END IF;
END;
1.2.2 Trigger trên bảng WORKING
* Tên trigger: check_duplicate_working_dates
* Mô tả: Khi thêm hoặc cập nhật ngày chấm công của nhân viên không được trùng
nhau
* Mã lệnh PL/SQL:
CREATE OR REPLACE TRIGGER check_duplicate_working_dates
BEFORE INSERT OR UPDATE ON WORKING
FOR EACH ROW
DECLARE
duplicate_count NUMBER;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
Kiểm tra nếu có ngày chấm công trùng nhau
SELECT COUNT(*) INTO duplicate_count
FROM WORKING
WHERE t_id = :NEW.t_id
AND TRUNC(w_checkin) = TRUNC(:NEW.w_checkin)
Trang 28AND w_id != NVL(:NEW.w_id, 0); Loại trừ bản ghi đang được cập nhật (UPDATE)
1.2.3 Trigger trên bảng TEACHERSTAFF
* Tên trigger: check_birth_before_start
* Mô tả: Khi thêm hoặc cập nhật ngày sinh nhân viên phải nhỏ hơn ngày vào làm
* Mã lệnh PL/SQL:
CREATE OR REPLACE TRIGGER check_birth_before_start
BEFORE INSERT OR UPDATE
ON TEACHERSTAFF
FOR EACH ROW
BEGIN
IF :new.t_birth is null and :new.t_startdate <> :old.t_startdate then
IF :new.t_startdate < :old.t_birth THEN
RAISE_APPLICATION_ERROR(-20002,'Ngày sinh phải nhỏ hơn ngày vào làm');
ELSE
DBMS_OUTPUT.PUT_LINE('GIAO TÁC THÀNH CÔNG');
END IF;
ELSIF :new.t_startdate is null and :new.t_birth <> :old.t_birth then
IF :new.t_birth > :old.t_startdate THEN
RAISE_APPLICATION_ERROR (-20002,'Ngày sinh phải nhỏ hơn ngày vào làm');
ELSE
Trang 29DBMS_OUTPUT.PUT_LINE ('GIAO TÁC THÀNH CÔNG');
END IF;
ELSE
Kiểm tra nếu ngày sinh lớn hơn hoặc bằng ngày vào làm
IF :new.t_birth >= :new.t_startdate THEN
RAISE_APPLICATION_ERROR (-20002,'Ngày sinh phải nhỏ hơn ngày vào làm');
1.2.4 Trigger trên bảng DISCOUNT
* Tên trigger: check_discount
* Mô tả: Khi thêm hoặc cập nhật phần trăm khuyến mãi phải nhỏ hơn 100
* Mã lệnh PL/SQL:
CREATE OR REPLACE TRIGGER CHECK_DISCOUNT
BEFORE INSERT OR UPDATE
1.2.5 Trigger trên bảng JOIN_COURSE
* Tên trigger: check_birth_before_c_start_ins
Trang 30* Mô tả: Khi thêm một đăng ký khóa học, ngày sinh của học viên phải nhỏ hơn ngày
bắt đầu khóa học
* Mã lệnh PL/SQL:
CREATE OR REPLACE TRIGGER check_birth_before_c_start_ins
BEFORE INSERT ON JOIN_COURSE
FOR EACH ROW
DECLARE
birthdate STUDENT.S_BIRTH%TYPE;
course_startdate COURSE.C_START%TYPE;
BEGIN
Lấy giá trị ngày sinh của học viên
SELECT s_birth INTO birthdate FROM STUDENT WHERE s_id = :NEW.s_id;
Lấy giá trị ngày bắt đầu khóa học
SELECT c_start INTO course_startdate FROM COURSE WHERE c_id = :NEW.c_id;
Kiểm tra nếu ngày sinh lớn hơn ngày bắt đầu khóa học
IF birthdate > course_startdate THEN
RAISE_APPLICATION_ERROR (-20001, 'Ngày sinh phải nhỏ hơn ngày bắt đầu khóa học.');
END IF;
END;
1.2.6 Trigger trên bảng COURSE
* Tên trigger: check_birth_before_c_start_udt
* Mô tả: Khi cập nhật khóa học, ngày bắt đầu khóa học phải lớn hơn tất cả ngày
sinh các học viên học khóa học đó
* Mã lệnh PL/SQL:
CREATE OR REPLACE TRIGGER check_birth_before_c_start_udt
Trang 31BEFORE UPDATE ON COURSE
FOR EACH ROW
BEGIN
Kiểm tra nếu có học viên trong khóa học
IF :OLD.c_num > 0 THEN
Lấy ngày sinh của các học viên tham gia khóa học
FOR rec IN (SELECT S_BIRTH FROM STUDENT WHERE S_ID IN (SELECT S_ID FROM JOIN_COURSE WHERE c_id = :OLD.c_id)) LOOP Kiểm tra nếu ngày bắt đầu mới nhỏ hơn ngày sinh
IF :NEW.c_start < rec.S_BIRTH THEN
RAISE_APPLICATION_ERROR (-20001, 'Ngày bắt đầu không thể nhỏ hơn ngày sinh của các học viên trong khóa học.');
END IF;
END LOOP;
END IF;
END;
1.2.7 Trigger trên bảng COURSE
* Tên trigger: check_start_end
* Mô tả: Khi thêm hoặc cập nhật khóa học, ngày bắt đầu phải nhỏ hơn ngày kết
thúc
* Mã lệnh PL/SQL:
CREATE OR REPLACE TRIGGER CHECK_START_END
BEFORE INSERT OR UPDATE
ON COURSE
FOR EACH ROW
BEGIN
IF :new.c_start is null and :new.c_end <> :old.c_end then
IF :new.c_end < :old.c_start THEN
Trang 32RAISE_APPLICATION_ERROR (-20011,'Ngày kết thúc khóa học phải lớn hơn ngày bắt đầu.');
ELSE
DBMS_OUTPUT.PUT_LINE ('GIAO TÁC THÀNH CÔNG');
END IF;
ELSIF :new.c_end is null and :new.c_start <> :old.c_start then
IF :new.c_start > :old.c_end THEN
RAISE_APPLICATION_ERROR (-20011,'Ngày kết thúc khóa học phải lớn hơn ngày bắt đầu.');
ELSE
DBMS_OUTPUT.PUT_LINE ('GIAO TÁC THÀNH CÔNG');
END IF;
ELSE
Kiểm tra nếu ngày kết thúc nhỏ hơn ngày bắt đầu
IF :NEW.c_end < :NEW.c_start THEN
RAISE_APPLICATION_ERROR (-20011, 'Ngày kết thúc khóa học phải lớn hơn ngày bắt đầu.');
1.2.8 Trigger trên bảng RESULT
* Tên trigger: check_score_limit
* Mô tả: Khi thêm hoặc cập nhật kết quả học viên, điểm không lớn hơn 10
* Mã lệnh PL/SQL:
CREATE OR REPLACE TRIGGER check_score_limit
BEFORE INSERT OR UPDATE ON RESULT
FOR EACH ROW
BEGIN
Kiểm tra nếu điểm học viên lớn hơn 10
Trang 331.2.9 Trigger trên bảng JOIN_COURSE
* Tên trigger: check_discount_limit
* Mô tả: Khi thêm hoặc cập nhật đăng kí khóa học, với mỗi mã khuyến mãi, học
viên chỉ được áp dụng 1 lần
* Mã lệnh PL/SQL:
CREATE OR REPLACE TRIGGER check_discount_limit
BEFORE INSERT ON JOIN_COURSE
FOR EACH ROW
DECLARE
discount_count NUMBER;
BEGIN
Kiểm tra số lần áp dụng mã khuyến mãi cho sinh viên
SELECT COUNT(*) INTO discount_count
FROM JOIN_COURSE
WHERE s_id = :NEW.s_id AND d_id = :NEW.d_id;
Kiểm tra nếu sinh viên đã áp dụng mã khuyến mãi trước đó
IF discount_count > 0 THEN
RAISE_APPLICATION_ERROR (-20001, 'Sinh viên đã áp dụng mã
khuyến mãi trước đó.');
END IF;
END;
1.2.10 Trigger trên bảng JOIN_COURSE
* Tên trigger: check_class_capacity_ins
* Mô tả: Khi thêm đăng kí khóa học, sĩ số không vượt quá sức chứa của khóa học
* Mã lệnh PL/SQL:
CREATE OR REPLACE TRIGGER check_class_capacity_ins
BEFORE INSERT ON JOIN_COURSE
FOR EACH ROW
Trang 34DECLARE
v_capacity NUMBER;
v_current_count NUMBER;
BEGIN
Lấy sức chứa của khóa học
SELECT c_capacity INTO v_capacity FROM COURSE WHERE c_id =
:NEW.c_id;
Đếm số học viên hiện tại trong khóa học
SELECT COUNT(*) INTO v_current_count FROM JOIN_COURSE
WHERE c_id = :NEW.c_id;
Kiểm tra nếu sĩ số vượt quá sức chứa
IF v_current_count > v_capacity THEN
Nếu sĩ số vượt quá, gây ra lỗi
RAISE_APPLICATION_ERROR(-20004, 'Sĩ số vượt quá sức chứa của lớp học.');
END IF;
END;
1.2.11 Trigger trên bảng COURSE
* Tên trigger: check_class_capacity_udt
* Mô tả: Khi cập nhật khóa học, sức chứa không nhỏ hơn sĩ số của lớp đó
* Mã lệnh PL/SQL:
CREATE OR REPLACE TRIGGER check_class_capacity_udt
BEFORE UPDATE ON COURSE
FOR EACH ROW
DECLARE
v_num NUMBER;
BEGIN
Lấy sĩ số hiện tại của khóa học
SELECT COUNT(*) INTO v_num FROM JOIN_COURSE WHERE c_id = :NEW.c_id;
Trang 35
Kiểm tra nếu sức chứa mới nhỏ hơn sĩ số hiện tại
IF :NEW.c_capacity < v_num THEN
RAISE_APPLICATION_ERROR(-20001, 'Sức chứa không thể nhỏ hơn sĩ
số hiện tại của khóa học.');
END IF;
END;
2.Procedure trong oracle
*Định nghĩa:
- Procedure hay còn gọi là thủ tục, nó dùng để gom một nhóm lệnh SQL cùng xử
lý một mục đích cụ thẻ nào đó, sau đó đặt cho nó một cái tên và khai bao tham số truyền vào để sau này mỗi khi cần sử dụng thì ta chỉ cần gọi tên và truyền tham số
- Stored procedure có thể được tái sử dụng và chuyển sang bất cứ ứng dụng nào muốn sử dụng chúng Stored procedure có thể “trưng ra” giao diện database cho tất
cả các ứng dụng, vì vậy lập trình viên không cần viết lại các chức năng đã hỗ trợ sẵn trong stored procedure trong tất cả các chương trình
- Stored procedure cũng rất an toàn Quản trị viên cơ sở dữ liệu có thể gán quyền cho ứng dụng truy xuất vào các stored procedures được chỉ định mà không cho phép truy cập đến các bảng (table) ở phía dưới
Bên cạch những tiện lợi như trên, stored procedure vẫn có 1 số bất tiện dưới đây:
- Stored procedure làm cho database server phải tốn nhiều tài nguyên về cả bộ nhớ lẫn xử lý Thay vì tập trung vào tính năng lưu trữ và nhận dữ liệu, bạn còn phải yêu
Trang 36cầu database server thực hiện 1 loạt các tính toán logic hay các thao tác xử lý phức tạp vốn không thuộc “sở trường” của database server
- Stored procedure chỉ chứa đựng các khai báo sql, vì vậy rất khó có thể viết 1 procedure nhằm thực hiện các thao tác xử lý phức tạp như các ngôn ngữ khác làm được ở tần ứng dụng như C#, Java, C++…
- Bạn cũng không thể debug stored procedure trong hầu hết các RDMBS và trong cả MySQL Có 1 vài cách để khắc phục nhược điểm này, tuy nhiên vẫn chưa hoàn hảo lắm
- Việc viết và bảo trì (maintain) stored procedure thường yêu cầu 1 loạt các kỹ năng chuyên biệt nhiều khi không phải là kỹ năng của lập trình viên Điều này dẫn đến các vấn đề trong cả khía cạnh phát triển ứng dụng và bảo trì sản phẩm
*Cú pháp khi viết một stored procedure:
CREATE [OR REPLACE] PROCEDURE <Tên Procedure>
/*Lệnh REPLACE dùng để thay thế nội dung procedure cũ*/
[(tham_số_1[, tham_số_2[, …tham_số_n])]
/*Có thể có 1 tham số, 2 tham số, n tham số, có thể không tham số*/
* Một số lưu ý khi viết procedure
1) Tham số truyền vào có thể ở dạng IN/OUT
- IN: Đây là tham số mặc định, tham số này là sẽ là dữ liệu truyền vào
- OUT: Tham số này sẽ là dữ liệu truyền ra
- IN OUT: Là tham số đặc, vừa là tham số đầu vào vừa là tham số đầu ra, và thường giá trị ban đầu bị thay đổi
Cách chạy Store procedure:
Trang 37Đăng ký khóa học cho học viên
in_d_id (IN) out_total (OUT)
Tính thành tiền khi áp
mã khuyến mãi
MAGV (IN) MAKH (IN)
Thêm một lịch dạy mới
MAGV (IN) MAKH (IN)
Chỉnh sửa một lịch dạy
LUONG (OUT)
Tính lương cho giảng viên
Trang 386 TINHDIEMTB MAKH (IN)
MAHV (IN) DIEM (OUT)
Tính điểm trung bình cho học viên
CUR (OUT)
Tính doanh thu theo tháng
CUR (OUT) TOTAL (OUT)
Tính doanh thu theo năm
học viên của trung tâm
nhân viên của trung tâm
khóa học của trung tâm
doanh thu của trung tâm
Trang 39
2.2 Mô tả các procedure trong đồ án môn học
a Đăng ký khóa học cho học viên
* Tên: DANG_KY_KHOA_HOC
* Nội dung: Đăng ký khóa học cho học viên
* Tham số đầu vào: in_s_id, in_c_id, in_d_id
* Tham số đầu ra: không có
SELECT c_num INTO v_num FROM course where c_id = in_c_id;
SELECT c_level INTO v_c_level FROM course where in_c_id = c_id;
SELECT s_level INTO v_s_level FROM student where in_s_id = s_id;
SELECT COUNT(*) INTO v_da_hoc FROM join_course WHERE c_id = in_c_id AND s_id = in_s_id;
Nếu học viên đã học khóa học đó, không thực hiện đăng ký lại
IF v_da_hoc > 0 THEN
raise_application_error(-20010, 'Học viên đã học khóa học này!');
Trang 40ELSE
Sinh viên chỉ được đăng kí khóa học cùng trình độ
IF v_s_level <> v_c_level THEN
raise_application_error(-20010, 'Trình độ khóa học không hợp lệ!');
ELSE
Lấy giá của khóa học dựa trên mã khóa học
SELECT c_fee INTO v_fee_basis FROM course WHERE c_id = in_c_id; Lấy giảm giá dựa trên mã khuyến mãi
IF in_d_id IS NOT NULL THEN
SELECT d_percentage / 100 * v_fee_basis INTO v_discount FROM discount WHERE d_id = in_d_id;
Tính giá sau khi áp dụng khuyến mãi
v_s_fee := v_fee_basis - v_discount;
ELSE
v_s_fee := v_fee_basis;
END IF;
Cập nhật sĩ số cho khóa học
UPDATE course SET c_num = v_num + 1 where c_id = in_c_id;
Thực hiện đăng ký khóa học bằng cách chèn dữ liệu vào bảng dang_ky_khoa_hoc
INSERT INTO join_course VALUES (in_s_id, in_c_id, in_d_id, v_s_fee, 'happenning');
[1] Kiểm tra học viên đã học khóa học đó hay chưa
[1.1] Nếu chưa, thì thực thi tiếp
[1.2] Nếu có thì hiện thông báo “Học viên đã học khóa học này!”