/*________========TẠO TRIGGER (10 câu)========________*/
--1. Tạo trigger kiểm tra số điện thoại của nhân viên CREATE TRIGGER [ck_sdtnv]
ON [dbo].[tblNhanVien]
FOR INSERT, UPDATE ASBEGIN
IF UPDATE(sSDT) BEGIN
DECLARE @sdt NVARCHAR( )11 SELECT @sdt = sSDT FROM inserted IF(LEN(@sdt 10 ) != ANDLEN(@sdt) != 11)
BEGIN
PRINT N'số điện thoại phải có 10 hoặc 11 số'
ROLLBACK TRAN END
IF(SUBSTRING(@sdt, 1 1 , ) != '0') BEGIN
PRINT N'số điện thoại phải bắt đầu bằng chữ số 0'
ROLLBACK TRAN END
DECLARE @i INT = 2 WHILE (@i <=LEN(@sdt))
BEGIN
IF(SUBSTRING(@sdt, @i 1 , ) <'0' OR SUBSTRING(@sdt @i 1 '9'), , ) >
BEGIN
PRINT N'số điện thoại chỉ được chứa những chữ số từ 0 đến 9'
ROLLBACK END
SET @i += 1 END END
END
INSERT INTO tblNhanVien (sTenNV, sNgaySinh sGioiTinh , , sDiaChi, sSDT sLuongcb sPhuCap, , ,sMaPB, sNgayVaoLam) VALUES (N' Trần Thị Hà' ' 12/03/1995', ,N'Nu',N'Hà Nội', '0663475042',7000000, 400,276, '05/04/2018') UPDATE tblNhanVien
SET sSDT ='06a3475042' WHERE sMaNV 3778=
/*2. khi có 1 nhân viên bị xoá khỏi bảng tblNhanVien (bằng bất kì cách nào) thì các đơn đặt hàng của nhân
viên đó sẽ được chuyển đều cho các nhân viên khác có số đơn đặt hàng
cao nhất nhưng ít hơn nhân viên bị xoá.
*/CREATE TRIGGER [xoa_tblnv]
ON [tblNhanVien]
INSTEAD OF DELETE ASBEGIN
DECLARE @manvxoa INT --mã nv của thằng bị xóa DECLARE @tonghoadonnvxoa INT -- tổng hóa đơn của nv bị xóa
DECLARE @tongdhcaonhat INT 1 = - -- tổng số đơn đặt hàng cao nhất nhưng ít hơn nhân viên bị xoá.
SELECT @manvxoa sMaNV = FROM deleted -- lấy ra mã nv bị xóa
IF NOT EXISTS( --nếu nv bị xóa chưa lập hóa đơn nào SELECT FROM * tblHoaDon
WHERE sMaNV @manvxoa= )BEGIN
DELETE FROM tblNhanVien -- sau khi thành công xóa nhân viên
WHERE sMaNV @manvxoa=
PRINT N'Xóa thành công nhân viên1' return
END
SELECT @tonghoadonnvxoa = COUNT(sMaHD) FROM tblHoaDon -- lấy ra tổng hóa đơn của nv bị xóa
WHERE sMaNV @manvxoa=
SELECT TOP 1 @tongdhcaonhat = COUNT(sMaHD) FROM tblHoaDon
GROUP BY sMaNV --lấy ra tổng số đơn đặt hàng cao nhất nhưng ít hơn nhân viên bị xoá.
HAVING sMaNV != @manvxoa AND COUNT(sMaHD ) <=
@tonghoadonnvxoa
ORDER BY COUNT(sMaHD) DESC
IF(@tongdhcaonhat = - 1)--nếu không có nv nào thỏa mãn điều kiện thì k được xóa và kết thúc trigger
BEGIN
PRINT N'Không xóa được nhân viên này' ROLLBACK
return END
DECLARE contronv CURSOR SCROLL--tạo con trỏ quản lý mã nhân viên sẽ được chuyển đơn hàng của nv bị xóa
FOR(SELECT sMaNV FROM tblHoaDon GROUP BY sMaNV
HAVING COUNT(sMaHD @tongdhcaonhat ) = AND sMaNV != @manvxoa
)
DECLARE controHD CURSOR --tạo con trỏ quản lý mã hóa đơn của thằng nv bị xóa
FOR(SELECT sMaHD FROM tblHoaDon WHERE sMaNV @manvxoa= )
OPEN controHD -- mở con trỏ OPEN contronv
DECLARE @i INT = 0
DECLARE @manvthaythe INT --mã nv thỏa mãn đk DECLARE @mahdcuanvcu INT --mã hóa đơn của nv bị xóa
FETCH NEXT FROM controHD INTO @mahdcuanvcu FETCH FIRST FROM contronv INTO @manvthaythe WHILE (@i @tonghoadonnvxoa< )
BEGIN
UPDATE tblHoaDon -- sửa mã nv thành mã nv thỏa mãn điều kiện
SET sMaNV @manvthaythe= WHERE sMaHD = @mahdcuanvcu FETCH NEXT FROM controHD INTO
@mahdcuanvcu
FETCH NEXT FROM contronv INTO
@manvthaythe
IF(@@FETCH_STATUS != ) 0 BEGIN
FETCH FIRST FROM contronv INTO @manvthaythe
END SET @i +=1 END
CLOSE contronv DEALLOCATE contronv CLOSE controHD DEALLOCATE controHD
DELETE FROM tblNhanVien -- sau khi thành công xóa nhân viên
WHERE sMaNV @manvxoa= PRINT N'Xóa thành công nhân viên2' END
DELETE FROM tblNhanVien WHERE sMaNV 38=
--3. Tạo trigger không cho cùng 1 lúc 2 khách hàng đều thuê 1 phòng
CREATE OR ALTER TRIGGER [check_thue_phong]
ON [dbo].[tblChi_tiet_hoa_don_phong]
FOR INSERT, UPDATE ASBEGIN
IF UPDATE(sMap) OR UPDATE(sNgayThue ) OR UPDATE(sNgayTra)
BEGIN
DECLARE @map INT
DECLARE @ngaythue DATETIME DECLARE @ngaytra DATETIME DECLARE @maHD INT
SELECT @map sMap= , @ngaythue = sNgayThue ,
@ngaytra sNgayTra @maHD sMaHD = , = FROM inserted DECLARE contro CURSOR
FOR SELECT sNgayThue sNgayTra , FROM tblChi_tiet_hoa_don_phong
WHERE sMap = @map AND @maHD sMaHD!=
OPEN contro
DECLARE @ckngaythue DATETIME DECLARE @ckngaytra DATETIME
FETCH NEXT FROM contro INTO @ckngaythue ,
@ckngaytra
WHILE (@@FETCH_STATUS = 0) BEGIN
DECLARE @Max DATETIME @ngaythue= DECLARE @Min DATETIME @ngaytra= IF(@ngaythue @ckngaythue < )
SET @Max = @ckngaythue IF(@ngaytra > @ckngaytra)
SET @min @ckngaytra=
/*NOTE: kiểm tra xem trong khoẳng thời gian đó đã có phòng bị khách thuê chưa bằng cách kiểm tra 2 khoảng thời gian có giao nhau hay không nếu nó giao nhau nghĩa là phòng đấy đã có người thuê rồi giống như kiểm tra 2 đoạn thẳng.
A1 /---/ B1, A2 /---/ B2 có giao nhau không vậy chỉ cần tìm Max đầu A và tìm Min đầu B rồi xem giá trị Min có lớn hơn . Max hay không nếu nó lớn hơn nghĩa là 2 đoạn thẳng giao nhau
*/
IF(@Max < @Min) BEGIN
PRINT N'Phòng đã có người thuê' ROLLBACK
RETURN END
FETCH NEXT FROM contro INTO
@ckngaythue, @ckngaytra END CLOSE contro DEALLOCATE contro PRINT N'INSERT COMPLETE' ENDEND
SELECT FROM * tblChi_tiet_hoa_don_phong INSERT INTO tblChi_tiet_hoa_don_phong
VALUES (368, 454,'2020-01-13 00:00:00.000', '2020-01-14') --4. Tạo trigger kiểm tra tuổi của nhân viên đủ 18 và không quá 50CREATE OR ALTER TRIGGER [ck_tuoi]
ON tblNhanVien FOR INSERT, UPDATE ASBEGIN
IF UPDATE (sNgaysinh) BEGIN
DECLARE @ngaysinh DATETIME
SELECT @ngaysinh = sNgaysinh FROM inserted IF(DATEDIFF day( , @ngaysinh, GETDATE()) / 365
>= 18 AND DATEDIFF(day, @ngaysinh GETDATE, ()) / 365 <=
50) BEGIN
PRINT N'đã đủ 18 tuổi và ít hơn 50 tuổi'
ELSEEND BEGIN
PRINT N'chưa đủ 18 tuổi hoặc cao hơn 50 tuổi'
ROLLBACK RETURN END
PRINT N'INSERT COMPLETE'END END
INSERT INTO tblNhanVien (sTenNV, sNgaySinh sGioiTinh , , sDiaChi, sSDT sLuongcb sPhuCap, , ,sMaPB, sNgayVaoLam) VALUES (N' Trần Thị Hồng','12/03/2007' N'Nu', ,N'Hà Nội', '0634753042',7000000, 400,276, '05/04/2018')
/*5. Tạo Trigger kiểm soát giới tính của nhân viên chỉ là nam hoặc nữ
*/CREATE OR ALTER TRIGGER [ck_nv_GT1]
ON [dbo].[tblNhanVien]
FOR INSERT ASBEGIN
DECLARE @gt NVARCHAR(3)
SELECT @gt sGioiTinh = FROM inserted IF(@gt != 'Nam' AND @gt 'Nu'!= )
BEGIN
PRINT N'Giới tính ' @gt + + N' không hợp lệ' ROLLBACK
RETURN END
PRINT 'INSERT COMPLETE' END
INSERT INTO tblNhanVien (sTenNV, sNgaySinh sGioiTinh , , sDiaChi, sSDT sLuongcb sPhuCap, , ,sMaPB, sNgayVaoLam) VALUES (N' Trần Thị Hồng','12/03/2002' N'Nua', ,N'Hà Nội', '0634753042',7000000, 400,276, '05/04/2018')
/*
6. Tạo Trigger không cho thay đổi giới tính, ngày sinh, ngày vào làm của nhân viên
*/
CREATE OR ALTER TRIGGER [ck_nv_GT2]
ON [dbo].[tblNhanVien]
FOR UPDATE ASBEGIN
IF UPDATE (sGioiTinh) BEGIN
PRINT N'không được thay đổi giới tính của nhân viên'
ROLLBACK RETURN END
IF UPDATE (sNgaysinh) BEGIN
PRINT N'không được thay đổi ngày sinh của nhân viên'
ROLLBACK
RETURN END
IF UPDATE (sNgayVaoLam) BEGIN
PRINT N'không được thay đổi ngày vào làm của nhân viên'
ROLLBACK RETURN END
ENDUPDATE tblNhanVien SET sGioiTinh ='nu'
UPDATE tblNhanVien
SET sNgayVaoLam = '2021/8/17'
UPDATE tblNhanVien
SET sNgaysinh = '2007/5/20'
/*7. Tạo trigger kiểm soát chỉ có nhân viên thu ngân mới được lập hóa đơn
*/CREATE OR ALTER TRIGGER [nv_hd]
ON [dbo].[tblHoaDon]
FOR INSERT, UPDATE ASBEGIN
IF UPDATE([sMaNV]) BEGIN
DECLARE @manv INT
DECLARE @tenbp NVARCHAR(20)
SELECT @manv sMaNV = FROM inserted SELECT @tenbp = sTenPB FROM tblNhanVien nvv INNER JOIN tblBoPhanQuanLy bp ON bp sMaPB .
= nvv.sMaPB
WHERE nvv.sMaNV = @manv IF (@tenbp !=N'thu ngân')
BEGIN
PRINT N'Nhân viên này khônng có quyền lập hóa đơn'
ROLLBACK RETURN ENDEND
ENDINSERT tblHoaDon(sMaKH, sMaNV sNgayLap, ) VALUES (3, 2, '2021/8/17')
--8. Tạo trigger kiểm tra số điện thoại của Khach hang CREATE TRIGGER [ck_sdtKH]
ON tblKhachHang FOR INSERT, UPDATE ASBEGIN
IF UPDATE(sSDTKH) BEGIN
DECLARE @sdt NVARCHAR( )11
SELECT @sdt = sSDTKH FROM inserted IF(LEN(@sdt 10 ) != ANDLEN(@sdt) != 11)
BEGIN
PRINT N'số điện thoại phải có 10 hoặc 11 số'
ROLLBACK TRAN END
IF(SUBSTRING(@sdt, 1 1 , ) != '0')
BEGIN
PRINT N'số điện thoại phải bắt đầu bằng chữ số 0'
ROLLBACK TRAN END
DECLARE @i INT = 2 WHILE (@i <=LEN(@sdt))
BEGIN
IF(SUBSTRING(@sdt, @i 1 , ) <'0' OR SUBSTRING(@sdt @i 1 '9'), , ) >
BEGIN
PRINT N'số điện thoại chỉ được chứa những chữ số từ 0 đến 9'
ROLLBACK SET @i += 1END
END END
ENDINSERT INTO tblKhachHang (sTenKH sGioiTinh sCCCD , , , sSDTKH)
VALUES( N' Nguyễn Hồng Vân', N'Nu', 0234530492, '0354307102')
UPDATE tblKhachHang SET sSDTKH ='06a3475042' WHERE sMaKH = 471 /*
9. Tạo trigger kiểm tra một Bộ phận quản lí tồn tại hay không trước khi thêm một nhân viên mới
*/CREATE OR ALTER TRIGGER [bpql_nv]
ON tblnhanvien INSTEAD OF INSERT AS
BEGIN
DECLARE @mapb INT
SELECT @mapb sMaPB = FROM inserted
IF NOT EXISTS(
SELECT FROM * tblBoPhanQuanLy WHERE sMaPB @mapb=
) BEGIN
PRINT N'không có bộ phận nào có mã là ' + CAST(@mapb AS NVARCHAR( ))20
ROLLBACK RETURN END
ELSEBEGIN
DECLARE @tennv NVARCHAR( )20 DECLARE @sngaysinh DATETIME DECLARE @sgioitinh NVARCHAR( )3 DECLARE @diachi NVARCHAR(50) DECLARE @sdt NVARCHAR( )11 DECLARE @luong FLOAT( )2 DECLARE @phucap FLOAT( )2 DECLARE @ngayvaolam DATETIME SELECT @tennv = sTenNV @sngaysinh , = sNgaysinh, @sgioitinh = sGioiTinh, @diachi sDiaChi @sdt = , = sSDT, @luong = sLuongcb, @phucap sPhuCap @ngayvaolam= ,
= sNgayVaoLam FROM inserted
INSERT INTO tblNhanVien (sTenNV, sNgaySinh , sGioiTinh, sDiaChi sSDT sLuongcb sPhuCap, , , ,sMaPB,
sNgayVaoLam)
VALUES (@tennv, @sngaysinh @sgioitinh , ,
@diachi, @sdt, @luong, @phucap, @mapb, @ngayvaolam) END
ENDINSERT INTO tblNhanVien (sTenNV, sNgaySinh sGioiTinh , , sDiaChi, sSDT sLuongcb sPhuCap, , ,sMaPB, sNgayVaoLam) VALUES (N'sô lô lê vinh','12/03/2002',N'Nu',N'Hà Nội', '0634753042',7000000, 400, 331 ,'05/04/2018')
/*10. Thêm cột Tổng tiền (float) vào bảng tblHoaDon, sau đó tạo trigger sao cho giá trị tổng tiền dv tự động thay đổi khi khách hàng sử dụng hoặc thay đổi một dịch vụ hoặc khi khách hàng thuê phòng hay giá phòng thay đổi
*/
ALTER TABLE tblkhachhang ADD sTongTien FLOAT(2)
--cập nhật lại tổng tiền của từng hóa đơn UPDATE tblHoaDon
SET sTongTien =ISNULL([tong tien dv], 0) + ISNULL([tong tien p], 0)
FROM [dbo].[tblHoaDon] hd LEFT JOIN (
SELECT cdv.sMaHD,SUM(cdv.sGiaNiemYet *
cdv sSoLuong. ) AS[tong tien dv] FROM tblChi_tiet_hoa_don_dv cdv GROUP BY cdv.sMaHD
) a ON a.sMaHD = hd sMaHD. LEFT JOIN(
SELECT cdp.sMaHD,SUM(cdp.sGiaPhong * DATEDIFF day( , sNgayThue, sNgayTra)) AS[tong tien p] FROM
tblChi_tiet_hoa_don_phong cdp GROUP BY cdp.sMaHD ) b ON b.sMaHD = hd sMaHD. GO
--tạo TRIGGER1 kiểm soát sự thay đổi trên bảng chi tiết dv CREATE OR ALTER TRIGGER [HD_dv]
ON [dbo].[tblChi_tiet_hoa_don_dv]
FOR INSERT, UPDATE AS
BEGIN
IF UPDATE([[sGiaNiemYet]]) OR UPDATE([sSoLuong]) BEGIN
DECLARE @giadvm FLOAT(2)
DECLARE @giadvcu FLOAT(2) = 0 DECLARE @slm INT
DECLARE @slc INT = 0 DECLARE @maHD INT
SELECT @maHD = sMaHD, @giadvm = sGiaNiemYet, @slm sSoLuong = FROM inserted
IF EXISTS (
SELECT FROM * deleted ) BEGIN
SELECT @giadvcu sGiaNiemYet = ,
@slc sSoLuong = FROM deleted END
UPDATE tblHoaDon
SET sTongTien += ((@giadvm @slm) - * (@giadvcu * @slc))
WHERE sMaHD = @maHD END END
UPDATE tblChi_tiet_hoa_don_dv SET sSoLuong = 3
WHERE sMaHD = 102 AND sMaDV = 170 SELECT FROM * tblDichVu dv
INNER JOIN tblChi_tiet_hoa_don_dv dvv ON dvv sMaDV . = dv sMaDV.
--tạo TRIGGER2 kiểm soát sự thay đổi trên bang chi tiết phong CREATE OR ALTER TRIGGER [HD_P]
ON [dbo].[tblChi_tiet_hoa_don_phong]
FOR INSERT ,UPDATE ASBEGIN
IF UPDATE([sGiaPhong]) OR UPDATE([sNgayThue] ) OR UPDATE([sNgayTra])
BEGIN
DECLARE @mahd INT DECLARE @giapm FLOAT( )2
DECLARE @ngaythuem DATETIME DECLARE @ngaytram DATETIME DECLARE @giapcu FLOAT(2) = 0
DECLARE @ngaythuecu DATETIME =GETDATE() DECLARE @ngaytracu DATETIME = GETDATE() SELECT @mahd sMaHD= , @giapm =
sGiaPhong, @ngaythuem sNgayThue= , @ngaytram = sNgayTra FROM inserted
IF EXISTS (
SELECT FROM * deleted ) BEGIN
SELECT @giapcu sGiaPhong= ,
@ngaythuecu sNgayThue @ngaytracu sNgayTra = , = FROM deleted
END
UPDATE tblHoaDon
SET sTongTien += ((@giapm * DATEDIFF day( , @ngaythuem @ngaytram - (@giapcu , )) * DATEDIFF day( , @ngaythuecu, @ngaytracu)))
WHERE sMaHD = @mahd END END
UPDATE tblChi_tiet_hoa_don_phong SET sNgayTra ='2018-10-05'
WHERE sMaHD = 150 AND sMap 102=