You are on page 1of 11

TÀI LIỆU THỰC HÀNH CSDL Nguyễn Minh Nhựt – HTCL2017 -17520867

CHỦ ĐỀ
TÀI LIỆU THỰC HÀNH CSDL Nguyễn Minh Nhựt – HTCL2017 -17520867

A. TRIGGER
Trigger là một thủ tục SQL được thực thi ở phía server khi có một sự kiện
insert, update, delete.

Trigger dùng để ràng buộc chặt chẽ dữ liệu nhiếu quan hệ.

Cách để thực hiện ràng buộc toàn vẹn trên nhiều quan hệ

 Bước 1: Xác định, bối cảnh, nội dung, bảng tầm ảnh hưởng
 Bước 2: Xác định tham số, bảng tham gia vào trigger
 Bước 3: Viết trigger, xác định trigger có liên quan đến nhiều record
và sử dụng con trỏ hay không?
 Bước 4: Kiểm tra câu trigger bằng các trường hợp

Cách xác định ràng buộc toàn vẹn, bối cảnh nội dung, bảng tầm ảnh hưởng
Cho lược đồ CSDL sử dụng cho tất cả bài thực hành về trigger
KHACHHANG (MaKH, HoTen, NgaySinh, SoDT, GioiTinh)
Tân từ: Khách hàng có mã khách hàng (MaKH), họ và tên khách hàng
(HoTen), ngày sinh của khách hàng (NgaySinh), số điện thoại (SoDT), giới
tính của khách hàng (GioiTinh).
DICHVU (MaDV, TenDV, LoaiDV, Phi, MoTa)
Tân từ: Nhà cung cấp có rất nhiều dịch vụ khác nhau để khách hàng đăng kí
để phân biệt các dịch vụ với nhau người ta thông qua mã dịch vụ (MaDV),
ngoài ra còn các thông tin khác là tên dịch vụ (TenDV), loại dịch vụ mà nhà
cung cấp (LoaiDV) loại dịch vụ gồm 3 loại chủ yếu là {Internet, TV, Thuê bao
điện thoại}, phí phải trả cho dịch vụ đó (Phi), mô tả ngắn gọn về dịch vụ
(MoTa).
1

Chủ đề: Trigger và Cursor


TÀI LIỆU THỰC HÀNH CSDL Nguyễn Minh Nhựt – HTCL2017 -17520867

HOPDONG (MaHD, MaKH, NgayDK)


Tân từ: Mã hợp đồng (MaHD), mã khách hàng (MaKH), ngày đăng kí
(NgayDK)
CHITIETHD (MaHD, MaDV, TrangThai)
Tân từ: Mã hợp đồng (MaHD), mã dịch vụ (MaDV), trạng thái dịch vụ
(TrangThai) có thể là ‘Open’ hoặc ‘Close’.
 Bước 0: Cài đặt cơ sở dữ liệu trên
CREATE DATABASE QLTIENNET
USE QLTIENNET

CREATE TABLE KHACHHANG(


MAKH int primary key,
HOTEN varchar(50),
NGAYSINH SMALLDATETIME,
SDT varchar(11),
GIOITINH varchar(3),
)

CREATE TABLE DICHVU(


MADV varchar(5) primary key,
TENDV varchar(50),
LOAIDV varchar(20),
PHI money,
MOTA varchar(255),
)

CREATE TABLE HOPDONG(


MAHD varchar(10) primary key,
MAKH int,
NGAYKY smalldatetime,
)

CREATE TABLE CTHD(


MAHD varchar(10),
MADV varchar(5),
2

Chủ đề: Trigger và Cursor


TÀI LIỆU THỰC HÀNH CSDL Nguyễn Minh Nhựt – HTCL2017 -17520867

TRANGTHAI varchar(5),
CONSTRAINT PK_CTHD PRIMARY KEY(MAHD,MADV)
)

ALTER TABLE HOPDONG


ADD CONSTRAINT FK_HOPDONG_KHACHHANG FOREIGN KEY(MAKH)
REFERENCES KHACHHANG(MAKH)

ALTER TABLE CTHD


ADD CONSTRAINT FK_HOPDONG_CTHD FOREIGN KEY(MAHD) REFERENCES
HOPDONG(MAHD)

ALTER TABLE CTHD


ADD CONSTRAINT FK_DV_CTHD FOREIGN KEY(MADV) REFERENCES
DICHVU(MADV)
 Ràng buộc toàn vẹn sau: Ngày đăng ký hợp đồng phải lớn hơn ngày
sinh của khách hàng.
o BỐI CẢNH: HOPDONG, KHACHHANG
kh  KHACHHANG , hd  HOPDONG : kh.MAKH  hd .MAKH
o NỘI DUNG:
 kh.NGAYSINH  hd .NGAYDK

o Bảng tầm ảnh hưởng


THÊM XÓA SỬA
KHACHHANG - - +(NgaySinh)
HOPDONG + - +(NgayDK)

Dấu -: Không ảnh hưởng  Không cần viết trigger


Dấu +: Ảnh hưởng  Viết Trigger
Vậy đối với ràng buộc trên ta phải viết 3 trigger: Trigger sửa
khách hàng ảnh hưởng đến ngày sinh, trigger thêm hợp đồng, sửa
hợp đồng ảnh hưởng đến ngày đăng kí.
3

Chủ đề: Trigger và Cursor


TÀI LIỆU THỰC HÀNH CSDL Nguyễn Minh Nhựt – HTCL2017 -17520867

 Dữ liệu trước khi viết trigger


BẢNG KHÁCH HÀNG
set dateformat dmy
INSERT INTO KHACHHANG VALUES(1,'Le Hoang Nguyen','25/03/2001','0773577204','Nam')
INSERT INTO KHACHHANG VALUES(2,'Phan Anh Nhat','26/03/2001','0352977905','Nam')
INSERT INTO KHACHHANG VALUES(3,'Tran Ngoc Giao','25/02/2001',null,'Nu')

select * from khachhang

BẢNG DỊCH VỤ
INSERT INTO DICHVU VALUES('DV01','Internet toc do cao','Internet',220000,'Toc do
upload: 5Mb/s, download: 10Mb/s')
INSERT INTO DICHVU VALUES('DV02','Internet toc do thuong','Internet',165000,'Toc
do upload: 1Mb/s, download: 5Mb/s')
INSERT INTO DICHVU VALUES('DV03','MyTV++','Truyen hinh cap',200000,'Xem duoc 200
kenh HD')
select * from dichvu

BẢNG HỢP ĐỒNG


INSERT INTO HOPDONG VALUES(1,1,'26/4/2020')
INSERT INTO HOPDONG VALUES(2,2,'26/5/2020')
INSERT INTO HOPDONG VALUES(3,2,'29/5/2020')
INSERT INTO HOPDONG VALUES(4,1,'15/5/2020')
INSERT INTO HOPDONG VALUES(5,1,'16/5/2020')
SELECT * FROM HOPDONG
4

Chủ đề: Trigger và Cursor


TÀI LIỆU THỰC HÀNH CSDL Nguyễn Minh Nhựt – HTCL2017 -17520867

 Bước 2, 3: Tiến hành viết trigger trên bảng HOPDONG

Vì một hợp đồng chỉ thuộc về một khách hàng nên khi thêm mới hoặc sửa
hợp đồng KHÔNG dùng con trỏ (cursor), nếu chúng ta sửa bảng khách
hàng ảnh hưởng đến một loạt hợp đồng thì sẽ dùng con trỏ (cursor) để
giải quyết vấn đề đó.

Cấu trúc một câu trigger

GO
CREATE TRIGGER <TenTrigger> ON <Bang>
FOR [INSERT, UPDATE, DELETE]
AS
BEGIN
……
END

Khai báo data tạm để không ảnh hưởng đến database

DECLARE @NGAYKY SMALLDATETIME, @NGAYSINH SMALLDATETIME

Lấy dữ liệu INSERT


5

Chủ đề: Trigger và Cursor


TÀI LIỆU THỰC HÀNH CSDL Nguyễn Minh Nhựt – HTCL2017 -17520867

SELECT @MAKH =MAKH, @NGAYKY =NGAYKY


FROM INSERTED

SELECT @NGAYSINH = NGAYSINH


FROM KHACHHANG
WHERE MAKH = @MAKH
Điều kiện kiểm tra
IF(@NGAYKY < @NGAYSINH)
BEGIN
PRINT 'ERROR: LOI NGAY DANG KI!'
ROLLBACK TRANSACTION
END
ELSE
BEGIN
PRINT 'Them Thanh cong'
END
Hoàn chỉnh một câu trigger  tô đen nhấn chạy

Thành công!
Câu trigger hoàn chỉnh
GO
CREATE TRIGGER themsua_hdong ON HOPDONG
FOR INSERT, UPDATE
AS
BEGIN
DECLARE @NGAYKY SMALLDATETIME, @NGAYSINH SMALLDATETIME,
@MAKH int
SELECT @MAKH =MAKH, @NGAYKY =NGAYKY
FROM INSERTED
6

Chủ đề: Trigger và Cursor


TÀI LIỆU THỰC HÀNH CSDL Nguyễn Minh Nhựt – HTCL2017 -17520867

SELECT @NGAYSINH = NGAYSINH


FROM KHACHHANG
WHERE MAKH = @MAKH
IF(@NGAYKY < @NGAYSINH)
BEGIN
PRINT 'ERROR: LOI NGAY DANG KI!'
ROLLBACK TRANSACTION
END
ELSE
BEGIN
PRINT 'Them Thanh cong'
END
END
Kiểm thử Trigger bảng hợp đồng
Trường hợp 1: Ngày hợp đồng < ngày sinh khách hàng báo lỗi và không
được lưu vào CSDL

Trường hợp 2: Ngày hợp đồng > ngày sinh khách hàng không báo lỗi và
được lưu vào CSDL
7

Chủ đề: Trigger và Cursor


TÀI LIỆU THỰC HÀNH CSDL Nguyễn Minh Nhựt – HTCL2017 -17520867

B. CURSOR
 Con trỏ cursor hoạt động linh hoạt cho những câu trigger khi sửa một
record ảnh hưởng đến nhiều record giả sử ta sửa ngày sinh của khách
hàng mà khách hàng đó kí nhiều hợp đồng thì phải check hết hợp đồng
của khách hàng đó nên sử dụng con trỏ
 Câu lệnh khai báo con trỏ

SELECT @MAKH =MAKH, @NGAYSINH = NGAYSINH


FROM INSERTED
/*Tìm những hóa đơn của khách hàng update bằng con
trỏ*/
DECLARE cursorDK CURSOR FOR
SELECT MAHD FROM HOPDONG WHERE MAKH = @MAKH

 Câu lệnh chạy con trỏ

OPEN cursorDK
FETCH NEXT FROM cursorDK into @MAHD
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @NGAYKY = NGAYKY
FROM HOPDONG
WHERE MAHD = @MAHD
IF(@NGAYKY < @NGAYSINH)
BEGIN
PRINT 'ERROR: LOI NGAY DANG KI!'
ROLLBACK TRANSACTION
END

FETCH NEXT FROM cursorDK -- Đọc dòng tiếp


INTO @MAHD
END
CLOSE cursorTOUR
PRINT 'Thanh cong'
8

Chủ đề: Trigger và Cursor


TÀI LIỆU THỰC HÀNH CSDL Nguyễn Minh Nhựt – HTCL2017 -17520867

DEALLOCATE cursorTOUR

 Code hoàn chỉnh trigger sử dụng con trỏ

GO
CREATE TRIGGER sua_khachhang ON KHACHHANG
FOR UPDATE
AS
BEGIN
DECLARE @NGAYKY SMALLDATETIME, @NGAYSINH SMALLDATETIME,
@MAKH int, @MAHD varchar(10)
SELECT @MAKH =MAKH, @NGAYSINH = NGAYSINH
FROM INSERTED
DECLARE cursorDK CURSOR FOR
SELECT MAHD FROM HOPDONG WHERE MAKH = @MAKH

OPEN cursorDK
FETCH NEXT FROM cursorDK into @MAHD
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @NGAYKY = NGAYKY
FROM HOPDONG
WHERE MAHD = @MAHD
IF(@NGAYKY < @NGAYSINH)
BEGIN
PRINT 'ERROR: LOI NGAY DANG KI!'
ROLLBACK TRANSACTION
END
ELSE
BEGIN
FETCH NEXT FROM cursorDK -- Đọc dòng tiếp
INTO @MAHD
END
END
CLOSE cursorDK
PRINT 'Thanh cong'
DEALLOCATE cursorDK
END
9

Chủ đề: Trigger và Cursor


TÀI LIỆU THỰC HÀNH CSDL Nguyễn Minh Nhựt – HTCL2017 -17520867

 Kiểm thử
SELECT * FROM HOPDONG

UPDATE ngày sinh của khách hàng 2 là ngày ‘27/7/2020’ sẽ báo lỗi

UPDATE ngày sinh của khách hàng 2 là ngày ‘27/7/2000’ sẽ thành


công
10

Chủ đề: Trigger và Cursor

You might also like