Ràng buộc trong CSDL Quản lý sinh viên với SQL Server
Khóa Thực chiến SQL cùng Kteam - Dự án quản lý sinh viên

Danh sách bài học
Ràng buộc trong CSDL Quản lý sinh viên với SQL Server
Nội dung bài viết Học nhanh
Dẫn nhập
Ở bài trước, chúng ta đã cùng nhau thực hành STORED PROCEDURE TRONG QUẢN LÝ SINH VIÊN VỚI SQL SERVER . Nội dung đề cập trong bài này thực sự không quá khó, mà còn có phần khá dễ chịu so với những bài trước. Tuy nhiên, phần bài tập về nhà sẽ nhiều "xương" nhé!
Trong bài này chúng ta sẽ cùng nhau đi vào một trong các phần cuối của khóa thực chiến với dự án Quản lý sinh viên đó chính là Ràng buộc trong CSDL dự án Quản lý sinh viên - phần 1.
Chúng ta hãy cùng nhau teamwork, thảo luận và hỗ trợ nhau trong dự án này để giải quyết bài toán thực tế một cách hoàn chỉnh dưới sự hướng dẫn của anh Kim Long - founder Howkteam nhé!
Nội dung
Để theo dõi bài này một cách tốt nhất, bạn nên có kiến thức về các phần:
- SỬ DỤNG SQL SERVER
- PHÂN TÍCH THIẾT KẾ PHẦN MỀM
- Đã xem qua bài PHÂN TÍCH ĐẶC TẢ DỰ ÁN QUẢN LÝ SINH VIÊN
- Đã xem qua bài CÀI ĐẶT CSDL VÀ XÁC ĐỊNH KHÓA CHÍNH, KHÓA NGOẠI LÊN SQL SERVER
- Đã xem qua bài NHẬP DỮ LIỆU VÀ THỰC HÀNH TRUY VẤN CƠ BẢN
- Đã xem qua bài FUNCTIONS TRONG QUẢN LÝ SINH VIÊN VỚI SQL SERVER
- Đã xem qua bài STORED PROCEDURE TRONG QUẢN LÝ SINH VIÊN VỚI SQL SERVER
Trong bài này, Kteam sẽ cùng các bạn tìm hiểu các nội dung:
- Giải quyết bài tập & củng cố kiến thức của bài trước
- Nhắc lại kiến thức Ràng buộc trong SQL Server
- Hướng dẫn thực hành ràng buộc
- Phân tích các vấn đề thực tế trong sử dụng ràng buộc
- Phần định hướng bài tập
- Các phần chia sẻ kinh nghiệm thực tế
Phần mềm sử dụng
Trong khóa học này, chúng ta sẽ học và thực hành trực tiếp với SQL Server. Nếu bạn chưa cài đặt SQL thì có thể xem qua bài
Bạn cũng có thể sử dụng các phiên bản khác từ 2008 trở lên. (vì không có nhiều khác biệt)
Ràng buộc
Hướng dẫn thực hành
Hãy cài đặt các ràng buộc toàn vẹn sau (bằng check constraint, unique constraint, rule hoặc trigger):
Source code mẫu của phần này sẽ được cập nhập sau khi khóa livestream kết thúc.
Miền giá trị
- ChuongTrinh mà chỉ có thể là ‘CQ‘ hoặc ‘CD‘ hoặc ‘TC’
- Chỉ có 2 học kỳ là ‘HK1‘ và ‘HK2‘
- Số tiết lý thuyết (GiangKhoa.soTietLyThuyet) tối đa là 120
- Số tiết thực hành (GiangKhoa.soTietThucHanh) tối đa là 60
- Số tín chỉ (GiangKhoa.soTinChi) của một môn học tối đa là 6
- Điểm thi (KetQua.diem) được chấm theo thang điểm 10 và chính xác đến 0.5 (làm bằng 2 cách: kiểm tra và báo lỗi nếu không đúng quy định; tự động làm tròn nếu không đúng qui định về độ chính xác)
Bài tập về nhà
Liên thuộc tính trên 1 quan hệ
- Năm kết thúc khóa học phải lớn hơn hoặc bằng năm bắt đầu
- Số tiết lý thuyết của mỗi giảng khóa không nhỏ hơn số tiết thực hành Liên bộ trên 1 quan hệ
Khảo sát buổi học
Hôm nay chúng ta đã hoàn buổi 6 của khóa THỰC CHIẾN SQL VỚI KTEAM - DỰ ÁN QUẢN
LÝ SINH VIÊN
Đây là bài khảo sát ngắn sau mỗi bài học, nhằm giúp Kteam đánh giá hiệu quả truyền tải của khóa học và hỗ trợ bạn các giải đáp các câu hỏi, kiến thức được đề cập đến trong bài.
Vui lòng giúp Kteam hoàn thành khảo sát để nhận được email theo dõi tiến độ cùng source code bài hôm nay, học liệu bài mới và đường dẫn tham gia khóa học mỗi ngày nhé!
Kết
Trong bài này,chúng ta đã tìm hiểu về Ràng buộc trong dự án quản lý sinh viên. Buổi học đã được diễn ra vào lúc 20h ngày 16/07/2019 tại phần trình chiếu của bài Ràng buộc trong dự án quản lý sinh viên trên Howkteam.com
Lưu ý: Sau bài học, Kteam sẽ gửi mail Khảo sát & giải đáp câu hỏi đến mail đã đăng ký của các bạn. Hoàn thành mail trước buổi học tiếp theo để xác nhận đã tham gia buổi học và đăng ký nhận đường dẫn kèm học liệu cho buổi học tiếp theo.
Ở bài sau, chúng ta sẽ tìm hiểu về RÀNG BUỘC TRONG DỰ ÁN QUẢN LÝ SINH VIÊN (phần 2)
Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của bạn để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”
Tải xuống
Tài liệu
Nhằm phục vụ mục đích học tập Offline của cộng đồng, Kteam hỗ trợ tính năng lưu trữ nội dung bài học Ràng buộc trong CSDL Quản lý sinh viên với SQL Server dưới dạng file PDF trong link bên dưới.
Ngoài ra, bạn cũng có thể tìm thấy các tài liệu được đóng góp từ cộng đồng ở mục TÀI LIỆU trên thư viện Howkteam.com
Đừng quên like và share để ủng hộ Kteam và tác giả nhé!

Thảo luận
Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.
Tác giả/Dịch giả

Nhà sáng lập Howkteam.com, KQuiz.vn & tác giả các khóa học C#, Auto, Unity3D, Python....
Với mong muốn mang đến kiến thức chất lượng, miễn phí cho mọi người, với tâm huyết phá bỏ rào cản kiến thức từ việc giáo dục thu phí. Tôi đã cùng đội ngũ Kteam đã lập nên trang website này để thế giới phẳng hơn.
Hãy cùng chúng tôi lan tỏa kiến thức đến cộng đồng!
Khóa học
Khóa Thực chiến SQL cùng Kteam - Dự án quản lý sinh viên
Trong các khóa học SỬ DỤNG SQL SERVER và PHÂN TÍCH THIẾT KẾ PHẦN MỀM, Kteam đã đề cập đến các kiến thức cần thiết để bạn có thể bắt đầu xây dựng một cơ sở dữ liệu với SQL server và truy vấn qua CSDL đó.
Ở combo Thực chiến SQL, chúng ta sẽ cùng nhau phân tích các CSDL đó từ đặc tả và ứng dụng các kiến thức đã học ở hai khóa trên vào việc giải quyết các yêu cầu thực tế của một CSDL. Trong bộ khóa học này các bạn sẽ đi qua các kiến thức từ cơ bản đến nâng cao qua các dự án khác nhau.
Nào! Chúng ta sẽ cùng nhau tìm hiểu dự án đầu tiên THỰC CHIẾN SQL CÙNG DỰ ÁN QUẢN LÝ SINH VIÊN
Đánh giá
Hy vọng anh làm nhiều khóa thực chiến hơn nữa. Hay quá anh ơi. Em quen giọng anh rồi. Mong anh ra nhiều series thực chiến về phần mềm, sql, tool,...
--10. Với các sinh viên có tham gia đầy đủ các môn học của khoa, chương trình mà sinh viên đang theo học, hãy in ra điểm trung bình cho các sinh viên này.
ALTER FUNCTION CHECK_NUMBER_OF_JOINED_SUBJECT(@MaSV VARCHAR(10))
RETURNS BIT
AS
BEGIN
DECLARE @RESULT_CHECKING BIT
DECLARE @NUMBER_SUBJECT_OF_STUDENT INT
DECLARE @NUMBER_SUBJECT_OF_MON_HOC INT
SET @RESULT_CHECKING = 0
SELECT @NUMBER_SUBJECT_OF_STUDENT = COUNT(*) FROM (SELECT DISTINCT dbo.Ket_qua.MaMH FROM dbo.Ket_qua
WHERE dbo.Ket_qua.MaSV = @MaSV) AS TEMP
SELECT DISTINCT @NUMBER_SUBJECT_OF_MON_HOC = COUNT(*) FROM dbo.Giang_khoa
LEFT JOIN dbo.Chuong_trinh_hoc ON Chuong_trinh_hoc.MaCT = Giang_khoa.MaCT
LEFT JOIN dbo.Mon_hoc ON Mon_hoc.MaMH = Giang_khoa.MaMH
LEFT JOIN dbo.Khoa ON Khoa.MaKhoa = Giang_khoa.MaKhoa
LEFT JOIN dbo.Lop ON Lop.Ma_Khoa = Khoa.MaKhoa
LEFT JOIN dbo.Khoa_hoc ON Khoa_hoc.MaKH = Lop.MaKH
LEFT JOIN dbo.Sinh_Vien ON Sinh_Vien.Malop = Lop.MaLop
WHERE dbo.Giang_khoa.Nam_hoc <= dbo.Khoa_hoc.Nam_ket_thuc AND dbo.Giang_khoa.Nam_hoc >= dbo.Khoa_hoc.Nam_bat_dau AND @MaSV = dbo.Sinh_Vien.MaSV
IF(@NUMBER_SUBJECT_OF_MON_HOC = @NUMBER_SUBJECT_OF_STUDENT)
BEGIN
SET @RESULT_CHECKING = 1
END
RETURN @RESULT_CHECKING
END
GO
ALTER FUNCTION UF_AVG_SCORE(@MaSV VARCHAR(10))
RETURNS FLOAT
AS
BEGIN
DECLARE @DTB FLOAT
SET @DTB = NULL
IF(@MaSV = NULL)
SET @DTB = NULL
IF(DBO.CHECK_NUMBER_OF_JOINED_SUBJECT(@MaSV)=1)
BEGIN
SELECT @DTB = dbo.SCORE_AVARAGE(@MaSV)
END
RETURN @DTB
END
GO
--TEST
SELECT DBO.UF_AVG_SCORE('0212001')
SELECT DBO.UF_AVG_SCORE('0311002')
SELECT DBO.UF_AVG_SCORE('0212002')
SELECT DBO.UF_AVG_SCORE('0212003')
SELECT DBO.UF_AVG_SCORE('0212004')
SELECT DBO.UF_AVG_SCORE('0311001')
--10. Với các sinh viên có tham gia đầy đủ các môn học của khoa, chương trình mà sinh viên đang theo học, hãy in ra điểm trung bình cho các sinh viên này.
ALTER FUNCTION CHECK_NUMBER_OF_JOINED_SUBJECT(@MaSV VARCHAR(10))
RETURNS BIT
AS
BEGIN
DECLARE @RESULT_CHECKING BIT
DECLARE @NUMBER_SUBJECT_OF_STUDENT INT
DECLARE @NUMBER_SUBJECT_OF_MON_HOC INT
SET @RESULT_CHECKING = 0
SELECT @NUMBER_SUBJECT_OF_STUDENT = COUNT(*) FROM (SELECT DISTINCT dbo.Ket_qua.MaMH FROM dbo.Ket_qua
WHERE dbo.Ket_qua.MaSV = @MaSV) AS TEMP
SELECT DISTINCT @NUMBER_SUBJECT_OF_MON_HOC = COUNT(*) FROM dbo.Giang_khoa
LEFT JOIN dbo.Chuong_trinh_hoc ON Chuong_trinh_hoc.MaCT = Giang_khoa.MaCT
LEFT JOIN dbo.Mon_hoc ON Mon_hoc.MaMH = Giang_khoa.MaMH
LEFT JOIN dbo.Khoa ON Khoa.MaKhoa = Giang_khoa.MaKhoa
LEFT JOIN dbo.Lop ON Lop.Ma_Khoa = Khoa.MaKhoa
LEFT JOIN dbo.Khoa_hoc ON Khoa_hoc.MaKH = Lop.MaKH
LEFT JOIN dbo.Sinh_Vien ON Sinh_Vien.Malop = Lop.MaLop
WHERE dbo.Giang_khoa.Nam_hoc <= dbo.Khoa_hoc.Nam_ket_thuc AND dbo.Giang_khoa.Nam_hoc >= dbo.Khoa_hoc.Nam_bat_dau AND @MaSV = dbo.Sinh_Vien.MaSV
IF(@NUMBER_SUBJECT_OF_MON_HOC = @NUMBER_SUBJECT_OF_STUDENT)
BEGIN
SET @RESULT_CHECKING = 1
END
RETURN @RESULT_CHECKING
END
GO
ALTER FUNCTION UF_AVG_SCORE(@MaSV VARCHAR(10))
RETURNS FLOAT
AS
BEGIN
DECLARE @DTB FLOAT
SET @DTB = NULL
IF(@MaSV = NULL)
SET @DTB = NULL
IF(DBO.CHECK_NUMBER_OF_JOINED_SUBJECT(@MaSV)=1)
BEGIN
SELECT @DTB = dbo.SCORE_AVARAGE(@MaSV)
END
RETURN @DTB
END
GO
--TEST
SELECT DBO.UF_AVG_SCORE('0212001')
SELECT DBO.UF_AVG_SCORE('0311002')
SELECT DBO.UF_AVG_SCORE('0212002')
SELECT DBO.UF_AVG_SCORE('0212003')
SELECT DBO.UF_AVG_SCORE('0212004')
SELECT DBO.UF_AVG_SCORE('0311001')
Bài tập về nhà
Thêm 1 quan hệ
XepLoai:
maSV
diemTrungBinh
ketQua
hocLuc
Đối với những sinh viên có ketQua là ”Đạt‘ thì hocLuc được xếp loại như sau:
· diemTrungBinh >= 8 thì hocLuc là ”Giỏi”
· 7 < = diemTrungBinh < 8 thì hocLuc là ”Khá” Còn lại là ”Trung bình”
USE Student_Management
GO
CREATE TABLE Xeploai
(
MaSV VARCHAR(10) PRIMARY KEY,
DTB FLOAT,
KQ NVARCHAR(20),
HOCLUC NVARCHAR(20)
FOREIGN KEY(MaSV) REFERENCES dbo.Sinh_Vien(MaSV)
)
GO
INSERT INTO DBO.Xeploai(dbo.Xeploai.MaSV)
SELECT DISTINCT dbo.Ket_qua.MaSV FROM dbo.Ket_qua
GO
CREATE FUNCTION UF_CHECK_NUMBER_OF_UNDER_4_SCORE(@MaSV VARCHAR(10))
RETURNS INT
AS
BEGIN
DECLARE @TRACKING INT
SELECT @TRACKING = COUNT(*) FROM dbo.Ket_qua LEFT JOIN
(SELECT dbo.Ket_qua.MaSV,dbo.Ket_qua.MaMH, MAX(dbo.Ket_qua.Lan_thi) AS LAST_EXAM
FROM dbo.Ket_qua
WHERE MaSV = @MaSV
GROUP BY dbo.Ket_qua.MaSV,dbo.Ket_qua.MaMH) AS TEMPL_TABLE ON TEMPL_TABLE.MaMH = Ket_qua.MaMH AND TEMPL_TABLE.MaSV = Ket_qua.MaSV
WHERE dbo.Ket_qua.Lan_thi = TEMPL_TABLE.LAST_EXAM AND Diem_thi <= 4
RETURN @TRACKING
END
GO
SELECT dbo.UF_CHECK_NUMBER_OF_UNDER_4_SCORE('0212001')
GO
CREATE FUNCTION UF_KETQUA(@MaSV VARCHAR(10))
RETURNS NVARCHAR(20)
AS
BEGIN
DECLARE @KET_QUA NVARCHAR(20)
DECLARE @DTB FLOAT
SET @DTB = dbo.SCORE_AVARAGE(@MaSV)
SET @KET_QUA = N'KHÔNG ĐẠT'
IF (@MaSV = NULL)
SET @KET_QUA = NULL
IF(@DTB>5 AND dbo.UF_CHECK_NUMBER_OF_UNDER_4_SCORE(@MaSV)<=2)
SET @KET_QUA = N'ĐẠT'
RETURN @KET_QUA
END
GO
CREATE FUNCTION UF_HOCLUC(@MaSV VARCHAR(10))
RETURNS NVARCHAR(30)
AS
BEGIN
DECLARE @HOCLUC NVARCHAR(30) = NULL
DECLARE @DTB FLOAT
DECLARE @KET_QUA NVARCHAR(20)
SET @KET_QUA = dbo.UF_KETQUA(@MaSV)
SET @DTB = dbo.SCORE_AVARAGE(@MaSV)
IF (@KET_QUA = N'ĐẠT')
BEGIN
IF(@DTB>=8)
SET @HOCLUC = N'Giỏi'
ELSE IF(@DTB>7)
SET @HOCLUC = N'Khá'
ELSE
SET @HOCLUC = N'Trung bình'
END
RETURN @HOCLUC
END
GO
UPDATE dbo.Xeploai
SET DTB = dbo.SCORE_AVARAGE(MaSV)
GO
UPDATE dbo.Xeploai
SET dbo.Xeploai.KQ = dbo.UF_KETQUA(MaSV)
GO
UPDATE dbo.Xeploai
SET HOCLUC = dbo.UF_HOCLUC(MaSV)
KẾT QUẢ :
MaSV
DTB
KQ
HOCLUC
212001
6.75
ĐẠT
Trung bình
212002
6
ĐẠT
Trung bình
212003
6.33333333
ĐẠT
Trung bình
212004
9
ĐẠT
Giỏi
CREATE FUNCTION CHECK_NUMBER_OF_JOINED_SUBJECT(@MaSV VARCHAR(10))
RETURNS BIT
AS
BEGIN
DECLARE @RESULT_CHECKING BIT
DECLARE @NUMBER_SUBJECT_OF_STUDENT INT
DECLARE @NUMBER_SUBJECT_OF_MON_HOC INT
SET @RESULT_CHECKING = 0
SELECT DISTINCT @NUMBER_SUBJECT_OF_STUDENT = COUNT(*) FROM dbo.Ket_qua WHERE @MaSV = dbo.Ket_qua.MaSV
SELECT DISTINCT @NUMBER_SUBJECT_OF_MON_HOC = COUNT(*) FROM dbo.Mon_hoc
IF(@NUMBER_SUBJECT_OF_MON_HOC = @NUMBER_SUBJECT_OF_STUDENT)
BEGIN
SET @RESULT_CHECKING = 1
END
RETURN @RESULT_CHECKING
END
GO
CREATE FUNCTION UF_AVG_SCORE(@MaSV VARCHAR(10))
RETURNS FLOAT
AS
BEGIN
DECLARE @DTB FLOAT
SET @DTB = NULL
IF(@MaSV = NULL)
SET @DTB = NULL
IF(DBO.CHECK_NUMBER_OF_JOINED_SUBJECT(@MaSV)=1)
BEGIN
SELECT @DTB = dbo.SCORE_AVARAGE(@MaSV)
END
RETURN @DTB
END
GO
--TEST
SELECT DBO.UF_AVG_SCORE('0212001')
SELECT DBO.UF_AVG_SCORE('0311002')
SELECT DBO.UF_AVG_SCORE('0212002')
SELECT DBO.UF_AVG_SCORE('0212003')
SELECT DBO.UF_AVG_SCORE('0212004')
SELECT DBO.UF_AVG_SCORE('0311001')
Chào HowKTeam!
Sau khi mình làm FUNC, PROC, TRIGGE cho các bài tập đầy đủ, thì mình mở Bảng Điểm để kiểm tra lại các lệnh truy vấn có sai sót gì ko, thì phát hiện ra cột Diem_Thi của bảng Điểm bị thay đổi NULL toàn bộ, sau đó mình có nhập lại điểm, phù hợp theo các TRIGGE đã tạo, nhưng khi tắt & mở lại bảng Điểm thì vẫn NULL, 1 số dòng thì lại có nhưng kết quả ko đúng như ban đầu mình đã nhập.
Rất mong các bạn hỗ trợ, chia sẽ. Cảm ơn HowKTeam rất nhiều.
/* Câu 8: Số tiết lý thuyết của mỗi giảng khóa không nhỏ hơn số tiết thực hành
Liên bộ trên 1 quan hệ */
-- Cách 1: Dùng CHECK
--ALTER TABLE dbo.Giang_Khoa
--ADD CONSTRAINT TVDT_So_Tiet
--CHECK (STLT >= STTH)
--GO
-- Cách 2: Dùng TRIGGER
ALTER TRIGGER TVDT_So_Tiet
ON dbo.Giang_Khoa
FOR INSERT, UPDATE
AS
BEGIN
--DECLARE @STLT INT;
--DECLARE @STTH INT;
--SELECT @STLT = Inserted.STLT FROM Inserted
--SELECT @STTH = Inserted.STTH FROM Inserted
--IF (@STLT < @STTH)
--PRINT N'Số tiết lý thuyết của mỗi giảng khóa không nhỏ hơn số tiết thực hành !'
--ROLLBACK
IF NOT EXISTS (SELECT * FROM Inserted
WHERE Inserted.STLT !< Inserted.STTH)
BEGIN
RAISERROR(N'Số tiết lý thuyết của mỗi giảng khóa không nhỏ hơn số tiết thực hành !', 16, 1)
ROLLBACK TRANSACTION
END
END
GO