3. TRIGGER LÀ GÌ?
Trigger là một trường hợp đăc biệt của store procedure, nó có hiệu lực khi
ta thay đổi dữ liệu trên 1 bảng dữ liệu cụ thể, hoặc các xử lý làm thay đổi
dữ liệu của các lệnh: insert, update, delete.
Trigger có thể chứa các lệnh truy vấn từ các bảng khác hoặc bao gồm
những lệnh SQL phức tạp.
Trigger chạy 1 cách tự động: chúng được kích hoạt ngay tức thì khi có sự
thay đổi dữ liệu trên bảng dữ liệu.
3
4. CÚ PHÁP TẠO TRIGGER
CREATE TRIGGER trigger_name
ON table_name
FOR [INSERT, UPDATE, DELETE]
AS
BEGIN
{Khai báo các biến xử lí}
{Các lệnh T-SQL}
END
4
5. LƯU Ý
Khi thực hiện một Trigger thì SQL tự động tạo 2
bảng Inserted và Deleted trong bộ nhớ chính và cục bộ cho mỗi Trigger,
có nghĩa là khi áp dụng Trigger trên bảng nào thì bảng Inserted và Deleted
sẽ được sử dụng riêng cho đó bảng đó.
Cấu trúc 2 bảng Inserted và Deleted được tạo ra sẽ giống hệt cấu trúc
của bảng mà Trigger đang thực thi và chúng chỉ tồn tại trong thời gian
Trigger đó thực thi
5
6. LƯU Ý
Inserted là bảng chứa các dòng dữ liệu vừa được Insert hay Update vào
bảng mà Trigger đang thực thi.
Deleted là bảng chứa các dòng dữ liệu mới được xóa khỏi bảng bằng
thao tác Delete hay Update.
Khi thực hiện thao tác Update, thì đồng nghĩa với việc sẽ xóa những dòng
dữ liệu cũ và thêm những dòng dữ liệu mới, khi đó tác Update sẽ vừa
đồng thời thêm dữ liệu là các dòng mới vào 2 bảng Inserted và Deleted
6
7. LƯU Ý
IF UPDATE (Column_List)
Trigger sẽ tự động thực hiện khi có thay đổi trên cột nhất định nào đó, thay
vì chỉ định Trigger kích hoạt trên cả bảng.
7
8. QUẢN LÝ TRIGGER
Xoá Trigger
DROP TRIGGER table_name.trigger_name
Hiển thị trigger của database
sp_helptrigger Flight_Details
8
9. VÍ DỤ
CREATE TRIGGER CHECK_NGAYMH
ON HOADON
FOR UPDATE, INSERT
AS
IF UPDATE (NGHD)
BEGIN
DECLARE @NGHD SMALLDATETIME, @NGDK SMALLDATETIME
SET @NGHD= (SELECT NGHD FROM INSERTED)
SET @NGDK= (SELECT NGDK FROM KHACHHANG A, INSERTED B WHERE A.MAKH = B.MAKH)
IF (@NGHD<@NGDK)
BEGIN
PRINT 'NGHD PHAI LON HON NGDK'
ROLLBACK TRAN --Câu lệnh quay lui khi xử lý không thành công
END
END
9
10. VÍ DỤ
Trigger cho biến cố Delete không cho xoá trên bảng HOADON
CREATE TRIGGER CANNOT_DELETE
ON HOADON
FOR DELETE
AS
ROLLBACK TRAN
10
12. CURSOR – CON TRỎ?
Cursor là kiểu dữ liệu cơ bản dùng để duyệt qua từng dòng dữ liệu trả về
từ câu truy vấn SELECT, giúp ta có thể có những xử lý khác nhau cho
từng dòng dữ liệu cụ thể.
12
13. CÁC BƯỚC SỬ DỤNG
Khai báo con trỏ
Mở con trỏ
Duyệt và xử lý con trỏ
Đóng con trỏ
Xoá các tham chiếu tới con trỏ
13
14. KHAI BÁO CON TRỎ:
DECLARE <Cursor_Name> CURSOR
[LOCAL | GLOBAL]
[FORWARD ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC |FAST_FORWARD]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
[TYPE_WARNING]
FOR <Select Statements>
[FOR UPDATE [OF Column_name[,….N]]]
Lưu ý: câu lệnh select không chứa các mệnh đề into, Compute, Compute
by
14
15. KHAI BÁO CON TRỎ:
Phạm vi: [LOCAL | GLOBAL]
Local :chỉ sử dụng trong phạm vi khai báo
Global :sử dụng chung cho cả kết nối (mặc định)
Di chuyển: [FORWARD ONLY | SCROLL]
ForWard_Only :chỉ di chuyển một hướng từ trước ra sau(mặc định)
Scroll : di chuyển tùy ý
15
16. KHAI BÁO CON TRỎ:
Các loại Cursor: [STATIC | KEYSET | DYNAMIC]
Static : dữ liệu trên Cursor không thay đổi mặt dù dữ liệu trong bảng nguồn
thay đổi (mặc định)
Dynamic :dữ liệu trên Cursor sẻ thay đổi mặt dù dữ liệu trong bảng nguồn thay
đổi
KeySet :giống Dynamic nhưng những dòng được thêm hay thay đổi giá trị khóa
trên bảng nguồn không thông qua Cursor sẽ không hiển thị trong Cursor.
Xử lý đồng thời: [READ_ONLY | SCROLL_LOCKS]
Read_Only :chỉ đọc(mặc định)
Scroll_Lock : đọc/ghi
16
17. KHAI BÁO CON TRỎ:
FOR <LỆNH SELECT>
FOR UPDATE [OF column_name [,...n]]
Nếu chỉ định OF column_name [,...n] chỉ những cột liệt kê mới được sửa đổi.
Nếu chỉ định UPDATE mà không chỉ định danh sách cột, thì tất cả các cột đều
có khả năng cập nhật trừ phi chỉ định READ_ONLY.
17
18. MỞ CON TRỎ:
OPEN <Cursor_name>
Để có thể đọc được các dòng dữ liệu bên trong cursor trước tiên bạn cần
phải mở cursor ra bằng lệnh OPEN.
Hoạt động bên trong của lệnh này thực ra là hệ thống sẽ thực hiện câu
lệnh truy vấn SELECT đã được chỉ định trong lệnh định nghĩa biến cursor
trước đó.
18
19. DUYỆT VÀ XỬ LÝ CON TRỎ
FETCH [NEXT| PRIOR | FIRST |LAST| ABSOLUTE n]
FROM <Cursor_name> [INTO <Var_list>]
FETCH FIRST: Truy xuất hàng đầu tiên.
FETCH NEXT: Truy xuất hàng tiếp theo
FETCH PRIOR: Truy xuất hàng trước hàng hiện tại.
FETCH LAST: Truy xuất hàng cuối cùng.
FETCH ABSOLUTE n: n là một số nguyên dương, truy xuất hàng n trong
con trỏ.
19
20. DUYỆT VÀ XỬ LÝ CON TRỎ
Biến trạng thái:
@@FETCH _STATUS: Trả về một số nguyên cho biết kết quả của lệnh truy
xuất cuối cùng của con trỏ.
@@FETCH_STATUS nếu <>0 thất bại
@@FETCH_STATUS nếu = 0 thàng công
@@CURSOR_ROWS: Trả về tổng số hàng hiện tại trong con trỏ đang mở.
20
21. ĐÓNG CON TRỎ
CLOSE <Cursor_name>
Dùng câu lệnh CLOSE để đóng cursor. Một số tài nguyên (memory
resource) sẽ được giải phóng nhưng cursor vẫn còn được khai báo và có
thể OPEN trở lại.
DEALLOCATE <Cursor_name>
Dùng câu lệnh DEALLOCATE để phóng thích hoàn toàn các tài nguyên
dành cho cursor (kể cả tên của cursor).
21
22. VÍ DỤ
DECLARE @au_lname varchar(40), @au_fname varchar(20)
DECLARE Employee_Cursor CURSOR FOR
SELECT LastName, FirstName FROM Northwind.dbo.Employees
OPEN Employee_Cursor
FETCH NEXT FROM Employee_Cursor INTO @au_lname, @au_fname
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Author:' + @au_fname + ' ' + @au_lname
FETCH NEXT FROM Employee_Cursor INTO @au_lname, @au_fname
END
CLOSE Employee_Cursor
DEALLOCATE Employee_Cursor
22
24. FUNCTION (HÀM)
Giống như thủ tục, hàm (function) là nhóm các lệnh T-SQL thực hiện chức
năng nào đó. Khác với thủ tục, các hàm sẽ trả về một giá trị ngay tại lời
gọi của nó.
Ngoài những hàm do hệ quản trị cơ sở dữ liệu cung cấp sẵn, người sử
dụng có thể định nghĩa thêm các hàm nhằm phục vụ cho mục đích riêng
của mình.
Hàm cũng có thể được lưu giữ ngay trên database dưới dạng Store
procedure.
24
25. CÁC LOẠI HÀM
Các hàm do người dùng định nghĩa thường có 2 loại:
Loại 1 là Hàm với giá trị trả về là “dữ liệu kiểu bảng” – Table-valued Functions;
Loại 2 là Hàm với giá trị trả về là một giá trị – Scalar-valued Functions và các
hàm này cũng sẽ được Hệ quản trị phân thành 2 nhóm.
25
26. CÚ PHÁP TẠO HÀM
CREATE FUNCTION <function_name>
([@argument1 datatype1 [mode1] ,
@argument2 datatype2 [mode2],
... ])
RETURNS datatype
AS
BEGIN
-- Khai báo biến sử dụng
-- Code nội dung của hàm
-- Trả về giá trị của hàm.
END;
26
27. CÚ PHÁP TẠO HÀM (tt)
function_name: Tên hàm phải tuân theo qui tắc định danh và không
trùng với tên của các hàm hệ thống có sẵn
argument: Tên tham số của hàm được khai báo ngay sau tên hàm và
được bao bởi cặp dấu (), Nếu hàm có nhiều tham số thì các khai báo phân
cách nhau bởi dấu phẩy và phải bao hồm 2 phần: Tên tham số được bắt
đầu bởi dấu @, Kiểu dữ liệu của tham số
mode: INPUT, OUTPUT, hoặc không cần viết.
datatype: Kiểu dữ liệu của tham số
27
28. HÀM NỘI TUYẾN
Hàm với giá trị trả về dưới dạng bảng và được gọi là hàm nội tuyến (inline
function).
Việc sử dụng hàm loại này cung cấp khả năng như khung nhìn nhưng cho
phép chúng ta sử dụng được các tham số và nhờ đó tính linh hoạt sẽ cao
hơn.
CREATE FUNCTION tên_hàm ([danh_sách_tham_số])
RETURNS TABLE
AS
RETURN (câu_lệnh_select)
28
29. CHÚ Ý
Cú pháp của hàm nội tuyến phải tuân theo các qui tắc sau:
Kiểu trả về của hàm phải được chỉ định bởi mệnh đề RETURNS TABLE.
Trong phần thân của hàm chỉ có duy nhất một câu lệnh RETURN xác định giá
trị trả về của hàm thông qua duy nhất một câu lệnh SELECT. Ngoài ra, không
sử dụng bất kỳ câu lệnh nào khác trong phần thân của hàm.
29
30. VÍ DỤ
CREATE FUNCTION func_XemSV(@khoa SMALLINT)
RETURNS TABLE
AS
RETURN
(
SELECT masv,hodem,ten,ngaysinh
FROM sinhvien INNER JOIN lop
ON sinhvien.malop=lop.malop
WHERE khoa=@khoa
)
30
Ngày mua hàng (NGHD, bảng HOADON) của một khách hàng thành viên sẽ lớn hơn hoặc bằng ngày khách hàng đó đăng ký thành viên ( NGDK, bảng KHACHHANG)
Mặc định, cursor có phạm vi Global trên kết nối mà nó đã được tạo. Nghĩa là, bạn có thể sử dụng cursor trên các gói lệnh thực hiện trên kết nối đó, trừ phi bạn đóng và giải phóng Cursor. Nếu bạn mở Cursor chưa đóng thì sẽ bị lỗi và có khi bị treo cho đến khi đóng kết nối. Với lý do đó, khi không sử dụng Cursor Global, bạn nên đóng và giải phóng Cursor.
Cursor Local có phạm vi hoạt động bên trong gói lệnh đã tạo nó. Và tự giải phóng khi kết thúc gói lệnh.
+ STATIC: (có thuộc tính READ ONLY). Khi tạo Cursor Static, dữ liệu từ các bảng gốc sẽ được Copy sang một bảng tạm trong CSDL tempdb
+ KEYSET: Giống như cursor Dynamic. Nhưng nó chỉ được tạo khi bảng nguồn có khai báo khóa, nếu không thì SQL tự động chuyển sang loại STATIC. Khi tạo Cursor KEYSET, Tập các khóa của bảng nguồn được lưu trên một table của CSDL tempdb. Do đó, việc xóa mẫu tin hoặc thay đổi giá trị khóa trên các bảng nguồn không thông qua Cursor sẽ không phản hồi trên tập mẫu tin
Cursor kiểu STATIC, KEYSET, và DYNAMIC mặc định dùng phương thức SCROLL.
-----------------------
Trừ phi sử dụng cursor trong một transaction, nếu không các table nguồn của cursor không tự động khóa dữ liệu. SQL Server cung cấp 4 chọn lựa cho phép ngăn cản việc sửa đổi mẫu tin cho tới khi thực hiện xong hoặc bằng cách khóa các table nguồn của cursor để bảo vệ các thay đổi của bạn.
READ_ONLY: Dùng khi chỉ truy xuất dữ liệu mà không sửa đổi dữ liệu.
SCROLL_LOCKS: Khoá các dòng đã được đọc vào Cursor đối với các User khác.
OPTIMISTIC WITH VALUES: Chỉ khóa các giá trị mà bạn vừa thay đổi. Nếu người dùng khác thay đổi các giá trị đó sẽ nhận được thông báo lỗi.
OPTIMISTIC WITH ROW VERSIONING: Khi muốn cả dòng được cập nhật, không chỉ một vài Fields trong nó.
Hàm trên nhận tham số đầu vào là khóa của sinh viên cần xem và giá trị trả về của hàm là tập các dòng dữ liệu cho biết thông tin về các sinh viên của khoá đó. Các hàm trả về giá trị dưới dạng bảng được sử dụng như là các bảng trong các câu lệnh SQL.