0% found this document useful (0 votes)
12 views27 pages

Trigger

trigger
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views27 pages

Trigger

trigger
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 27

30/6/2023

Chương 8
TRIGGER

Mục tiêu
Sau khi học xong chương này, SV có thể:
Biết Trigger là gì và khi nào sử dụng Trigger.
Nắm được các loại Trigger.
Nắm vững cú pháp tạo, xóa và cập nhật Trigger.
Tạo được Trigger khi thêm, xóa và cập nhật dữ liệu.

1
30/6/2023

Nội dung chi tiết


Trigger là gì?
Khi nào sử dụng Trigger?
Các loại Trigger
Các bảng tạm Inserted và Deleted
Tạo - Xóa - Cập nhật Trigger
Tạo Trigger khi thêm, xóa và cập nhật dữ liệu

Trigger là gì?
Trigger là một Stored Procedure không có tham số.
Trigger thực thi một cách tự động khi một trong ba câu lệnh Insert, Update, Dele

2
30/6/2023

Khi nào sử dụng Trigger?


Trigger thường được sử dụng để:
Kiểm tra các ràng buộc dữ liệu phức tạp mà không thể dùng constraint trên nhiều bảng ho
Gọi hành động "Rollback Tran" để hoàn tác, hủy thao tác cập nhật khi vi phạm ràng buộc.
Tính toán, tự động cập nhật giá trị để đảm bảo tính toàn vẹn dữ liệu.

Ưu điểm của Trigger


Sử dụng Trigger để kiểm tra tính toàn vẹn của CSDL.
Trigger có thể bắt lỗi logic ở mức CSDL.
Có thể dùng Trigger là một cách khác để thay thế việc thực hiện những công việc
Trigger rất hiệu quả khi sử dụng để kiểm soát những thay đổi của dữ liệu tro

3
30/6/2023

Nhược điểm của Trigger


Trigger chỉ là một phần mở rộng của việc kiểm tra tính hợp lệ của dữ liệu chứ kh
Trigger hoạt động ngầm trong CSDL, không hiển thị ở tầng giao diện. Do đó, kh
Trigger thực hiện các update lên bảng dữ liệu vì thế nó làm tăng lượng công việ
7

Các loại Trigger


INSTEAD OF Trigger
Chạy trước các hành động kiểm tra ràng buộc dữ liệu.
Dữ liệu chưa bị thay đổi.
FOR (AFTER) Trigger
Chạy sau các hành động kiểm tra ràng buộc dữ liệu.
Dữ liệu đã bị tạm thời thay đổi trong bảng.

4
30/6/2023

Các bảng tạm Inserted và Deleted


Khi Trigger được thực hiện, SQL tự động tạo ra 2 bảng tạm Inserted
Inserted: chứa dữ liệu được thêm mới khi thực thi câu lệnh Insert hoặc câu lệ
Deleted: Chứa dữ liệu bị xoá khi thực thi câu lệnh Delete hoặc chứa dữ liệu cũ
Hành động Update trong SQL Server: xoá dữ liệu cũ và thêm dữ liệu mớ
=> Sử dụng cả 2 bảng tạm Inserted và Deleted.
9

Tạo Trigger
Cú pháp:
CREATE TRIGGER Tên_Trigger ON Tên_bảng
{ INSTEAD OF | FOR | AFTER } { INSERT | DELETE | UPDATE } AS
Khối lệnh xử lý

10

5
30/6/2023

Quản lý Trigger
Xóa Trigger:
Cú pháp:
DROP TRIGGER Tên_Trigger

Cập nhật Trigger:


Cú pháp:
ALTER TRIGGER …

11

Tạo Trigger khi thêm dữ liệu


Thường dùng để kiểm tra:
Khóa ngoại
Miền giá trị
Liên thuộc tính trong cùng một bảng
Liên thuộc tính của nhiều bảng khác nhau
3 loại đầu tiên, chỉ dùng Trigger nếu muốn cung cấp các báo lỗi cụ th
12

6
30/6/2023

Tạo Trigger khi thêm dữ liệu


Các cấu trúc / lệnh thường dùng khi kiểm tra:
if else
if exists
raiserror
rollback tran

13

7
30/6/2023

Tạo Trigger khi thêm dữ liệu


VD1: Hãy tạo Trigger instead of ứng với hành động thêm mẩu tin mới vào bảng KETQUA (tt):

16

8
30/6/2023

Tạo Trigger khi xóa dữ liệu


Tương tự Trigger Insert, khi xóa cũng phải kiểm tra vi phạm các ràng buộc toàn v
VD1: Trigger ứng với hành động xóa mẩu tin trong bảng SINHVIEN => Kiểm tra
VD2: Trigger ứng với hành động xóa mẩu tin trong bảng KETQUA => Cập nhật
VD3: Trigger ứng với hành động xóa mẩu tin trong bảng DONHANG => Xóa các
18

9
30/6/2023

10
30/6/2023

11
30/6/2023

12
30/6/2023

Tạo Trigger khi cập nhật dữ liệu


Không được sửa thông tin khóa chính:
Cú pháp kiểm tra cột có bị sửa thông tin không?
if update(Tên_cột)
-- Khối lệnh xử lý
Khi cập nhật dữ liệu cũng phải kiểm tra vi phạm các ràng buộc toàn

25

Tạo Trigger khi cập nhật dữ liệu


VD: Hãy tạo Trigger instead of ứng với hành động sửa đổi mẩu tin trên bảng KE
Nếu thay đổi Mã SV và Mã môn học thì báo lỗi không được sửa khóa chính.
Nếu Điểm thay đổi thì cập nhật lại cột DTB trong bảng SINHVIEN.
Nếu Điểm cũ < 5 và Điểm mới ≥ 5 thì tăng số tín chỉ tích lũy của SV.
Nếu Điểm cũ ≥ 5 và Điểm mới <5 thì giảm số tín chỉ tín tích lũy của SV.

26

13
30/6/2023

14
30/6/2023

Bài tập ứng dụng


Sử dụng CSDL Quản lý sinh viên:
Bổ sung cột tổng số sinh viên (SOSV: int) trong bảng KHOA, cột điểm trung b
Hãy tạo các Trigger khi thêm – xóa – sửa dữ liệu của các bảng trong CSDL.

30

15
30/6/2023

----------------------Funcion-----------------------------
--5. Xây dựng hàm fn_DTB_MH(@mamh) trả về điểm TB của môn học có mã số truyền vào.
go
create function fn_DTB_MH1(@mamh varchar(2))
returns float
as
begin
declare @dtb float
select @dtb=AVG(diem) from ketqua where mamh=@mamh
return @dtb
end
/*6. Xây dựng thủ tục sp_CapNhatMH có sử dụng hàm fn_DTB_MH để cập nhật lại số tiết trong bảng
MONHOC
theo các qui tắc sau: Tăng 10 tiết nếu ĐTB của SV học dưới 5.
Tăng 5 tiết nếu ĐTB của SV học từ 5 ≤ ĐTB < 7
Không tăng số tiết nếu ĐTB của SV học ≥ 7 hoặc không
có SV học.*/
go
create proc sp_Update_Sotiet7(@mamh varchar(2))
as
if @mamh is null
begin
print 'Chua nhap mon' return
end
if not exists(select * from monhoc where mamh=@mamh)
begin
print 'Khong co mon '+@mamh return
end
if not exists(select * from ketqua where mamh=@mamh)
begin
print 'Mon '+@mamh+' chua co diem' return
end
declare @dtb float, @stt int
set @dtb=dbo.fn_DTB_MH(@mamh)
if @dtb<5 set @stt=10
if @dtb>=5 and @dtb<7 set @stt=5
if @dtb>=7 set @stt=0
update monhoc set sotiet=sotiet+@stt where mamh=@mamh
print 'Mon '+@mamh+' da duoc cap nhat so tiet'
go
exec dbo.sp_Update_Sotiet7 '01'

/*7. Xây dựng thủ tục sp_CapNhatMH_KyTuDau(@kytudau) có sử


dụng hàm fn_DTB_MH để cập nhật lại số tiết trong bảng MONHOC
cho các môn học mà tên có ký tự đầu là “T”.*/
go
create proc sp_CapNhatMH_KyTuDau(@mamh varchar(2), @ktd varchar(1))
as
if @mamh is null
begin
print 'Chua nhap mon' return
end
if not exists(select * from monhoc where mamh=@mamh)
begin
print 'Khong co mon '+@mamh return
end
if not exists(select * from ketqua where mamh=@mamh)
begin
print 'Mon '+@mamh+' chua co diem' return
end

16
30/6/2023

declare @dtb float, @stt int


set @dtb=dbo.fn_DTB_MH(@mamh)
if @dtb<5 set @stt=10
if @dtb>=5 and @dtb<7 set @stt=5
if @dtb>=7 set @stt=0
update monhoc set sotiet=sotiet+@stt where mamh=@mamh and @ktd='T%'
print 'Mon '+@mamh+' da duoc cap nhat so tiet'

go
exec dbo.sp_CapNhatMH_KyTuDau '01'

/*14. Xây dựng hàm fn_LocDSMH_CapNhatSoTiet để lọc danh sách môn


học (gồm các thông tin: mã MH, tên MH, ĐTB thi của SV, số tiết cũ,
số tiết mới) với số tiết mới của SV được tính theo các qui tắc sau:
• Không tăng số tiết nếu không có SV học hoặc ĐTB của SV học dưới 5.
• Tăng 5 tiết nếu ĐTB của SV học từ 5 ≤ ĐTB < 7
• Tăng 10 tiết nếu ĐTB của SV học ≥ 7*/
go
create function fn_LocDSMH_CapNhatSoTiet()
returns table
as
return
select mh.mamh, tenmh, STC=sotiet, DTb=AVG(diem),
STM=sotiet+case when AVG(diem)>=7 then 10
when AVG(diem)>=5 and
AVG(diem)<7 then 5
else 0 end
from monhoc mh inner join ketqua kq on mh.mamh=kq.mamh
group by mh.mamh, tenmh, sotiet
go
select * from dbo.fn_LocDSMH_CapNhatSoTiet()

/*8 Xây dựng hàm fn_DanhSachSinhVien_DTB(@makh) trả về danh


sách các SV của mã khoa truyền vào, gồm các thông tin: mã SV,
họ tên SV, ĐTB.*/

go
create function fn_DanhSachSinhVien_DTB(@makh varchar(2))
returns table
as
return
select sv.masv, Hoten=hosv+' '+tensv, dtb=avg(diem)
from sinhvien sv inner join ketqua kq on sv.masv=kq.masv
where @makh = makh
group by sv.masv, tensv, hosv
go
select * from dbo.fn_DanhSachSinhVien_DTB('AV')

/*9. Xây dựng hàm fn_DanhSachMonHoc(@masv) trả về danh sách


gồm các thông tin: mã môn học, tên môn học và điểm số tương
ứng của mã SV truyền vào.*/

go
create function fn_DanhSachMonHoc(@masv varchar(3))
returns table
as
return
select mh.mamh, tenmh, diem
from monhoc mh inner join ketqua kq on mh.mamh=kq.mamh
where @masv = kq.masv

17
30/6/2023

go
select * from dbo.fn_DanhSachMonHoc('A01')

/*10. Xây dựng hàm fn_DSSV_ThiMon(@mamh) để lọc danh sách SV


đã thi môn học với mã môn truyền vào, gồm các thông tin: mã SV,
họ tên SV, tên khoa.*/
go
create function fn_DSSV_ThiMon(@mamh varchar(2))
returns table
as
return
select sv.masv, Hoten=hosv+' '+tensv, tenkh
from monhoc mh inner join ketqua kq on mh.mamh=kq.mamh inner join sinhvien sv on
sv.masv=kq.masv inner join khoa kh on sv.makh=kh.makh
where @mamh = mh.mamh
go
select * from dbo.fn_DSSV_ThiMon('01')

/*11 Xây dựng hàm fn_DSKhoa_ThiMon(@mamh) để lọc danh sách


khoa có SV đã thi môn học với mã môn truyền vào.*/
go
create function fn_DSKhoa_ThiMon(@mamh varchar(2))
returns table
as
return
select Hoten=hosv+' '+tensv
from monhoc mh inner join ketqua kq on mh.mamh=kq.mamh inner join sinhvien sv on
sv.masv=kq.masv
where @mamh = mh.mamh
go
select * from dbo.fn_DSKhoa_ThiMon('02')

/*12. Xây dựng hàm fn_DSKhoa_ThiMon_Diem(@mamh) để lọc danh


sách khoa có SV đã thi môn học với mã môn truyền vào, gồm các
thông tin: mã khoa, tên khoa, điểm thi cao nhất, điểm thi thấp nhất
và ĐTB.*/
go
create function fn_DSKhoa_ThiMon_Diem(@mamh varchar(2))
returns table
as
return
select kh.makh, tenkh, Dcn=max(diem), Dtt=min(diem), dtb=avg(diem)
from ketqua kq inner join sinhvien sv on sv.masv=kq.masv inner join khoa kh on
kh.makh=sv.makh
where @mamh = kq.mamh
group by kh.makh, tenkh
go
select * from dbo.fn_DSKhoa_ThiMon_Diem('01')

/*13 Xây dựng hàm fn_LocDSSV_CapNhatHB(@makh) để lọc danh


sách SV (gồm các thông tin: mã SV, họ tên SV, học bổng mới) của
mã Khoa truyền vào, có cập nhật lại học bổng của SV theo các qui
tắc sau:
• Không cấp học bổng nếu ĐTB < 7
• Cấp học bổng 500.000đ nếu 7 ≤ ĐTB < 8
• Cấp học bổng 800.000đ nếu 8 ≤ ĐTB < 9
• Cấp học bổng 1.000.000đ nếu 9 ≤ ĐTB ≤ 10*/
go
create function fn_LocDSSV_CapNhatHB(@makh varchar(2))

18
30/6/2023

returns table
as
return
select sv.masv, Hoten=hosv+' '+tensv, HBM=hocbong+case when avg(diem) >=7 and
avg(diem) < 8 then 500000

when avg(diem) >=8 and avg(diem) < 9 then 800000

when avg(diem) >=9 and avg(diem) <=10 then 1000000

else 0 end
from ketqua kq inner join sinhvien sv on sv.masv=kq.masv inner join khoa kh on
kh.makh=sv.makh
where @makh = kh.makh
group by sv.masv, hosv, tensv, hocbong
go
select * from dbo.fn_LocDSSV_CapNhatHB('LS')

---------------------------Cursor----------------------
--9.Tạo một bảng tên MONHOC_1 có cấu trúc và dữ liệu dựa vào bảng
--MONHOC (chỉ lấy hai cột: MAMH, TENMH). Sau đó, sử dụng vòng lặp WHILE
--viết đoạn chương trình dùng để xóa từng dòng dữ liệu trong bảng
--MONHOC_1 với điều kiện câu lệnh bên trong vòng lặp khi mỗi lần thực hiện
--chỉ được phép xóa một dòng dữ liệu trong bảng MONHOC_1. Sau khi xóa một
--dòng thì thông báo ra màn hình nội dung “Đã xóa môn học ” + Tên môn học.
go
declare cur_sv cursor
for select mamh,tenmh
from MonHoc_01
open cur_sv
declare @mamh varchar(3), @tenmh nvarchar(50)
fetch next from cur_sv into @mamh,@tenmh
while @@FETCH_STATUS=0
begin
select mamh,tenmh
from MonHoc_01
where mamh=@mamh
delete from MonHoc_01
where mamh=@mamh
print N'Da xoa dong' + @tenmh
fetch next from cur_sv into @mamh,@tenmh
end
close cur_sv
deallocate cur_sv
--1.Duyệt cursor và xử lý hiển thị danh sách các SV gồm các thông tin: mã SV, họ
--tên SV, mã khoa, và có thêm cột tổng số môn thi.
go
declare cur_sv cursor
for select masv,hosv,tensv,makh
from sinhvien
open cur_sv
declare @masv char(3),@hosv nvarchar(15),@tensv nvarchar(7),@makh char(2),@tongsomonthi int
fetch next from cur_sv into @masv,@hosv,@tensv,@makh
while @@FETCH_STATUS=0
begin
select @tongsomonthi =isnull(count(mamh),0) from ketqua
where masv=@masv
print @masv +@hosv+ @tensv + @makh + cast(@tongsomonthi as nvarchar(10))
fetch next from cur_sv into @masv,@hosv,@tensv,@makh
end

19
30/6/2023

close cur_sv
deallocate cur_sv
--2.Duyệt cursor và xử lý hiển thị danh sách các môn học có thêm cột Ghi chú, biết
--rằng nếu đã có SV thi thì in ra “Đã có xxx SV thi”, ngược lại thì in ra “Chưa có SV
--thi”.
go
declare cur_sv cursor
for select mamh,tenmh
from monhoc mh
open cur_sv
declare @mamh char(2),@tenmh nvarchar(50),@ghichu int
fetch next from cur_sv into @mamh,@tenmh
while @@FETCH_STATUS=0
begin
select @ghichu=count(mamh)
from ketqua kq
where mamh=@mamh
if (@ghichu > 0)
print @mamh+' '+@tenmh+' '+ N'Da co '+ cast(@ghichu as nvarchar(10)) + ' SV thi'
else
print N'Chua co sinh vien thi'
fetch next from cur_sv into @mamh,@tenmh
end
close cur_sv
deallocate cur_sv
--3.Duyệt cursor và xử lý giảm học bổng của các SV theo các qui tắc sau:
--• Không giảm nếu ĐTB  8.5
--• Giảm 5% nếu 7.5 ≤ ĐTB < 8.5
--• Giảm 10% nếu 7 ≤ ĐTB < 7.5
go
declare cur_sv cursor
for select masv
from sinhvien
open cur_sv
declare @masv varchar(3),@tb int
fetch next from cur_sv into @masv
while @@FETCH_STATUS=0
begin
select @tb=avg(diem)
from ketqua
where masv = @masv
if @tb>=7.5 and @tb<8.5
update sinhvien set hocbong=hocbong*0.95
where masv=@masv
if @tb>=7 and @tb <7.5
update sinhvien set hocbong=hocbong*0.9
where masv=@masv
fetch next from cur_sv into @masv
end
close cur_sv
deallocate cur_sv
--SP
--1. Xây dựng Stored Procedure tên sp_KetQuaThi với tham số vào là
--mã số SV (giá trị mặc định là NULL) để hiển thị thông tin: Mã SV,
--Họ và tên, Tên môn và Điểm. Nếu không truyền vào mã số SV thì
--thủ tục sẽ liệt kê kết quả thi của tất cả các sinh viên.
go
create proc sp_KetQuaThi (@masv varchar(3) = null )
as
if @masv is null

11
0
30/6/2023

begin
select sv.masv,hosv+' '+tensv,tenmh,diem from sinhvien sv inner join ketqua kq on
kq.masv=sv.masv inner join
monhoc mh on kq.mamh=mh.mamh
return
end
if not exists (select * from sinhvien sv where masv=@masv)
begin
print N'Không có sinh viên này' + @masv
return
end
if (select count(*) from ketqua kq where masv=@masv) > 0
begin
select sv.masv,hosv+' '+tensv,tenmh,diem from sinhvien sv inner join ketqua kq on
kq.masv=sv.masv inner join
monhoc mh on kq.mamh=mh.mamh where sv.masv=@masv
return
end
else
print N'Sinh viên' +@masv +N'chưa thi môn nào'

go
exec sp_KetQuaThi 'A01'
--2. Xây dựng Stored Procedure tên sp_TongHocBongSVTheoKhoa
--với tham số vào là Tên khoa để tính tổng học bổng của các sinh
--viên thuộc khoa đó. Nếu Tên khoa không hợp lệ thì thông báo lỗi.
go
create proc sp_TongHocBongSVTheoKhoa (@tenkh nvarchar(50))
as
if not exists ( select * from khoa where tenkh=@tenkh)
begin
print N'Không có khoa này' +@tenkh
return
end
if not exists (select * from sinhvien sv inner join khoa kh on sv.makh=kh.makh where tenkh=@tenkh)
begin
print N'Khoa này' +@tenkh + N'chưa có sinh viên'
return
end
declare @tong int = 0
select @tong = sum(isnull(hocbong,0)) from sinhvien sv inner join khoa kh on sv.makh=kh.makh where
tenkh=@tenkh
if @tong = 0
begin
print N'Khoa này không có học bổng'
return
end
else
begin
print N'Tổng học bổng của khoa' +@tenkh +'là' + cast(@tong as nvarchar(10))
end

go
exec sp_TongHocBongSVTheoKhoa N'Anh Văn'

--3.Xây dựng Stored Procedure tên sp_DTB để tính điểm trung bình
--với 2 tham số vào là mã môn học và mã khoa.
go
create proc sp_DTB (@mamh varchar(2), @makh varchar(2))
as

11
1
30/6/2023

if not exists (select * from monhoc mh where mamh=@mamh)


begin
print N'Không tồn tại mã môn học ' +@mamh
return
end
if not exists (select * from khoa kh where makh=@makh)
begin
print N'Không có khoa này ' +@makh
return
end
if (select count(*) from sinhvien sv inner join ketqua kq on kq.masv=sv.masv inner join
khoa kh on sv.makh=kh.makh where kh.makh=@makh and mamh=@mamh) <=0
begin
print N'Khoa '+@mamh+ N'này chưa có sinh viên thi môn ' +@mamh
end
declare @dtb float = 0
select @dtb=avg(diem) from sinhvien sv inner join ketqua kq on kq.masv=sv.masv inner join
monhoc mh on kq.mamh=mh.mamh inner join khoa kh on sv.makh=kh.makh where
mh.mamh=@mamh and kh.makh=@makh
if @dtb = 0
begin
print N'Khoa'+@makh +N'chưa có sinh viên thi môn' +@mamh
end
else
begin
print N'Điểm trung bình của khoa'+@makh +N'thi môn' +@mamh+ N'là'+ cast(@dtb
as nvarchar(10))
end

go
exec sp_DTB '01','LS'
--4.Xây dựng Stored Procedure tên sp_HienThi_DSSV_TheoKhoa với
--tham số vào là mã khoa để hiển thị thông tin sinh viên thuộc Khoa
--đó và có thêm cột GHI CHÚ hiển thị “Đã thi xxx môn” nếu SV có kết
--quả thi, ngược lại thì hiển thị “Chưa có kết quả thi” nếu SV chưa thi
--môn nào.
go
create proc sp_HienThi_DSSV_TheoKhoa (@makh varchar(2))
as
if not exists (select * from khoa kh where makh = @makh)
begin
print N'Không tồn tại khoa ' +@makh
return
end
if (select count (*) from sinhvien sv where makh = @makh)>0
begin
select * , ghichu = (case when count(*) > 0 then 'Đã thi ' + count(*) +'môn'
else 'Chưa có kết quả thi' end )
from sinhvien sv inner join ketqua kq on sv.masv = kq.masv
end
go
exec sp_HienThi_DSSV_TheoKhoa 'AV'
--5.Xây dựng Stored Procedure tên sp_Them_SV để thêm 1 SV mới,
--cần kiểm tra ràng buộc dữ liệu trước khi thực hiện lệnh thêm
go
create proc sp_Them_SV (@masv varchar(2) ,@hosv nvarchar(50),@tensv nvarchar(50) ,@phai int=0,@ngaysinh
datetime,@noisinh nvarchar(50),@makh varchar(2) ,@hocbong int = 0)
as
if exists (select * from sinhvien sv where masv=@masv)
begin

11
2
30/6/2023

print N'Đã tồn tại sinh viên mã số ' +@masv


return
end
insert into sinhvien values (@masv,@hosv,@tensv,@phai,@ngaysinh,@noisinh,@makh,@hocbong)
print N'Đã thêm sinh viên'
--6.Xây dựng Stored Procedure tên sp_Xoa_SV để xóa 1 SV với tham
--số vào là mã SV muốn xóa, cần kiểm tra ràng buộc dữ liệu trước
--khi thực hiện lệnh xóa.
go
create proc sp_Xoa_SV(@masv varchar(2))
as
if not exists (select * from sinhvien sv where masv=@masv)
begin
print N'Mã sinh viên '+@masv +N'không tồn tại'
return
end
delete sinhvien where masv=@masv
print N'Đã xóa sinh viên ' +@masv

--1.Cho biết học bổng trung bình của SV khoa Tin Học là bao nhiêu?
--Nếu lớn hơn 100,000 thì in ra “không tăng học bổng”, ngược lại in ra “nên tăng học bổng”
go
if exists(select * from sinhvien sv inner join khoa kh on sv.makh=kh.makh where tenkh= N'Tin Học')
begin
declare @tb int
select @tb=avg(isnull(hocbong,0)) from sinhvien sv inner join khoa kh on sv.makh=kh.makh where
tenkh= N'Tin Học'
if @tb > 100000
print 'HBTB: '+ cast(@tb as varchar(10)) + N' Không tăng học bổng'
else
print 'HBTB: '+ cast(@tb as varchar(10)) + N' Nên tăng học bổng'
end
else
print N'Không có sinh viên khoa Tin Học'
--2.Sử dụng hàm DATENAME để tính xem có SV nào sinh vào ngày chủ
--nhật không? Nếu có thì in ra danh sách các SV đó, ngược lại thì in ra
--chuỗi “Không có SV nào sinh vào ngày Chủ Nhật”
go
if exists(select * from sinhvien sv where DATENAME(weekday,ngaysinh)='Sunday')
begin
select * from sinhvien sv where DATENAME(weekday,ngaysinh)='Sunday'
end
else print N'Không có SV nào sinh vào ngày Chủ Nhật'
--3.Hãy cho biết SV có mã số A01 đã thi bao nhiêu môn, nếu có thì in ra
--“SV A01
--đã thi xxx môn”, ngược lại thì in ra “SV A01 chưa có kết quả thi”
go
if exists(select * from sinhvien sv where masv='A01')
begin
declare @somonthi tinyint
select @somonthi=count(*) from ketqua kq where masv='A01'
if @somonthi>1
print N'SV A01 đã thi '+cast(@somonthi as varchar(10))+ N' môn'
else
print N'SV A01 chưa có kết quả thi'
end
else
print N'Không tồn tại sinh viên có mã A01'
--4.Hãy cho biết SV có mã số A01 đã thi đủ tất cả các môn chưa, nếu có thì
---in ra “SV A01 đã thi đủ tất cả các môn”, ngược lại thì in ra “SV A01

11
3
30/6/2023

--chưa thi đủ tất cả các môn”.


go
if exists(select * from sinhvien sv where masv='A01')
begin
if exists(select count(*) from ketqua kq inner join monhoc mh on kq.mamh=mh.mamh where
masv='A01'
group by masv
having count(*) >= all(select count(tenmh) from monhoc mh))
print N'SV A01 đã thi đủ tất cả các môn'
else
print N'SV A01 chưa thi đủ tất cả các môn'
end
else
print N'Không tồn tại sinh viên có mã A01'
--5.Hãy cho biết môn Vật lý nguyên tử đã SV thi chưa, nếu có thì in ra “Đã
--có SV thi môn Vật lý nguyên tử với điểm trung bình là xxx”, ngược lại
--thì in ra “Chưa có SV thi môn Vật lý nguyên tử”.
go
if exists(select * from sinhvien sv inner join ketqua kq on sv.masv=kq.masv inner join monhoc mh on
kq.mamh=mh.mamh
where tenmh=N'Vật lý nguyên tử')
begin
declare @diem tinyint
select @diem=diem from sinhvien sv inner join ketqua kq on sv.masv=kq.masv inner join monhoc mh
on kq.mamh=mh.mamh
where tenmh=N'Vật lý nguyên tử'
print N'Đã có SV thi môn Vật lý nguyên tử với điểm trung bình là '+cast(@diem as varchar(3))
end
else
print N'Chưa có SV thi môn Vật lý nguyên tử'
--6.Liệt kê danh sách các SV có bổ sung thêm cột hiển thị thứ trong tuần
--(bằng tiếng Việt) của ngày sinh.
select *,thutrongtuan=case when datename(weekday,ngaysinh)='Monday' then N'Thứ 2'
when datename(weekday,ngaysinh)='Tuesday'
then N'Thứ 3'
when
datename(weekday,ngaysinh)='Wednesday' then N'Thứ 4'
when datename(weekday,ngaysinh)='Thursday'
then N'Thứ 5'
when datename(weekday,ngaysinh)='Friday'
then N'Thứ 6'
when datename(weekday,ngaysinh)='Saturday'
then N'Thứ 7'
when datename(weekday,ngaysinh)='Sunday'
then N'Chủ nhật' end
from sinhvien sv
--7.Tính tổng các số nguyên từ 1 đến 100
go
declare @dem int = 0
declare @tong int = 0
while @dem < 100
begin
set @dem = @dem+1
set @tong = @tong + @dem
end
print N'Tong la: ' + cast(@tong as varchar(50))
--8.Tính tổng chẵn và tổng lẻ của các số nguyên từ 1 đến 100
go
declare @dem int = 0
declare @tongchan int = 0

11
4
30/6/2023

declare @tongle int = 0


while @dem < 100
begin
set @dem = @dem+1
if (@dem % 2 =0)
begin
set @tongchan = @tongchan +@dem
end
else
begin
set @tongle = @tongle + @dem
end
end
print N'Tong chan: ' + cast(@tongchan as nvarchar(50))
print N'Tong le: ' + cast(@tongle as nvarchar(50))

--=======================Trigger=================================--
alter table khoa add SOSV int
select * from khoa
update khoa set SOSV=(select count(*) from sinhvien where khoa.makh=sinhvien.makh)

alter table sinhvien add DTB float


select * from sinhvien
update sinhvien set dtb=(select avg(diem) from ketqua where sinhvien.masv=ketqua.masv)

alter table sinhvien add SOTC int


select * from sinhvien
update sinhvien set sotc=(select sum(sotiet/15) from ketqua inner join monhoc on ketqua.mamh=monhoc.mamh
where sinhvien.masv=ketqua.masv)
go
--SOSV
create trigger tg_InsertSV_SOSV on sinhvien
for insert
as
declare @makh varchar(2)
select @makh=makh from inserted
update khoa set sosv=(select count(*) from sinhvien where sinhvien.makh=@makh)
where khoa.makh=@makh
go
insert into sinhvien values('A09',N'Trần Văn',N'Chính',1,'24/12/1982',N'TP.HCM','TH',100000, null, null)
select * from sinhvien
select * from khoa
go
--DELETE SOSV--
create trigger tg_DeleteSV__SOSV on sinhvien
for delete
as
declare @masv varchar(3), @makh varchar(3)
select @masv=masv, @makh = makh from deleted
update khoa set SOSV=SOSV-1 where @makh=khoa.makh
go

go
delete sinhvien where masv = 'A09'
select * from sinhvien
select * from khoa

/*create trigger tg_UpdateSV_SOSV on sinhvien


for update
as

11
5
30/6/2023

*/
go
create trigger tg_UpdateSV_SOSV on sinhvien
for update
as
if update(masv)
begin
raiserror('Khong duoc sua khoa chinh', 16, 1)
rollback
return
end

--DTB, SOTC
/*create trigger tg_InsertKQ_DTB_SOTC on ketqua
for Insert
as
*/
go
create trigger tg_InsertKQ_DTB_SOTC on ketqua
for Insert
as
declare @masv char(3), @mamh char(2), @diem real
select @masv=masv, @mamh=mamh, @diem=diem from

/*create trigger tg_DeleteKQ_DTB_SOTC on ketqua


for Delete
as
*/
go
create trigger tg_InsertKQ_DTB_SOTC on ketqua
for delete
as
declare @masv char(3), @mamh char(2), @diem real
select @masv=masv, @mamh=mamh, @diem=diem from deleted
update sinhvien set dtb=(select avg(diem) from ketqua where @masv=masv) where masv=@masv

if @diem>=5
begin
declare @sotiet int
select @sotiet = sotiet from monhoc where @mamh=mamh
update sinhvien set SOTC=SOTC-@sotiet/15 where @masv=masv
end
/*create trigger tg_UpdateKQ_DTB_SOTC on ketqua
for Update
as
*/

go
create trigger tg_UpdateKQ_SOTC_DTB on ketqua
for update
as
if update(masv) or update(mamh)
begin
raiserror('Khong duoc sua khoa chinh', 16, 1)
rollback
return
end

declare @masv char(3), @mamh char(2), @diemcu real, @diemmoi real

11
6
30/6/2023

select @diemcu = diem from deleted


select @masv=masv, @mamh=mamh, @diemmoi=diem from inserted

update sinhvien set DTB=(select avg(diem) from ketqua where masv=@masv) where masv=@masv

declare @sotiet int


select @sotiet=sotiet from monhoc where mamh=@mamh
if @diemcu<5 and @diemmoi>=5
update sinhvien set sotc=sotc+@sotiet/15 where masv=@masv
if @diemcu>=5 and @diemmoi<5
update sinhvien set sotc=sotc-@sotiet/15 where masv=@masv

11
7

You might also like