Chất lượng của một CSDL được đánh giá một phần bởi tính nhất quán và độ chính xác của dữ liệu trong CSDL. Để đảm bảo tính tồn vẹn dữ liệu ta cĩ nhiều phương pháp, trigger là một phương pháp hữu hiệu.
Trigger là một loại stored procedure đặc biệt, nĩ được định nghĩa để tự động thực thi khi cĩ một câu lệnh Update, Insert, hoặc Delete được phát ra trên bảng hoặc View.
Trigger là một cơng cụ mạnh mà nĩ cĩ thể dùng để ràng buộc các qui tắc quản lý một các tự động khi dữ liệu bị hiệu chỉnh.
Trigger cũng cĩ thể nới rộng các tính tồn vẹn kiểm sốt logic của SQL Server. Trigger tự động thực thi, khơng thể gọi một trigger thi hành một cách trực tiếp.
Dùng trigger khi:
Ràng buộc tồn vẹn dữ liệu cho phù hợp với mơ hình quan hệ CSDL.
Kiểm sốt dữ liệu hiện tại khi cĩ thay đổi đến giá trị trong mẫu tin trong bảng. Kiểm tra dữ liệu nhập vào phù hợp với mối quan hệ dữ liệu giữa các bảng. Định nghĩa thơng báo lỗi của người dùng.
So sánh trạng thái của dữ liệu trước và sau hiệu chỉnh
Đặc điểm và giới hạn của trigger
Trigger (After trigger) là Reactive; constraints và instead of trigger là proactive. (Reactive: khi delete/insert một dịng vào table, thì sau khi insert thì trigger mới đuợc tự động thực thi thì gọi là reactive, proactive là kiểm tra trước khi Insert/Delete)
Các constraint được kiểm tra trước, sau đĩ mới tới trigger.
Các bảng cĩ thể cĩ nhiều trigger cho bất kỳ hành động nào. Tuy nhiên khơng nên dùng quá nhiều trigger trong cùng một bảng. SQl Server chỉ cho phép chỉ định trigger nào thi hành đầu tiên, thi hành cuối cùng, cịn các trigger khác thứ tự thi hành khơng xác định. Vì vậy, nếu cĩ quá nhiều trigger trên 1 đối tượng cĩ thể sẽ gặp nhiều rắt rối khi cĩ nhiều trigger khơng xác định thứ tự.
Khơng thể tạo trigger trên các đối tượng ở temporary.
Nên thiết kế trigger khơng trả về tập kết quả nhằm đảm bảo tính chất chuyển tác giữa các user và lập trình.
Các trigger cĩ thể xử lý hành động trên nhiều dịng.
Trigger khơng ngăn ngừa thay đổi cấu trúc, trigger chỉ quan tâm đến sự thay đổi dữ liệu trong bảng. Khi bạn xĩa đối tượng trong CSDL với các bước hợp lý, SQL Server sẽ cho phép xĩa đối tượng đĩ và trigger khơng thể kiểm sốt được.
Trigger Events: Cĩ 3 biến cố mà trigger sẽ tự động thực thi khi biến cố xảy ra, đĩ là Insert, Update, Delete. Trigger khơng thể được gọi một cách trực tiếp.
Cơ cấu thực thi trigger:
Khi insert hoặc update dữ liệu của bảng bật trigger, trigger sẽ lưu trữ dịng dữ liệu mới hoặc dịng dữ liệu đã hiệu chỉnh vào một bảng cĩ tên là Inserted trong bộ
nhớ cash, khi xĩa dữ liệu của bảng bật trigger lên, trigger sẽ lưu trữ dịng dữ liệu bị xĩa vào bảng cĩ tên là Deleted trong bộ nhớ cash. Các bảng tồn tại trong bộ nhớ và được truy vấn bởi các lệnh T-SQL trong các trigger. Bạn cĩ thể sử dụng thơng tin trong bảng inserted và Deleted để so sánh, lưu trữ, rollback,… nếu cần, khi đĩ bạn khơng cần tạo ra các biến để lưu trữ thơng tin và tốc độ truy xuất nhanh.
Hai loại trigger trong SQL Server 2000: INSTEAD OF và AFTER (nếu chỉ nĩi trigger cĩ nghĩa là nĩi đến AFTER Trigger)
FOR triggers và AFTER triggers: các trigger này chỉ được thực thi khi tất cả các thao tác Insert, Update hay Delete thực hiện xong. Tất cả các hành động tham chiếu và kiểm tra constraint cũng phải được thực hiện xong trước khi trigger thi hành. Loại trigger này chỉ cài đặt được trên bảng, khơng cài đặt được trên View. Khi tạo trigger và khơng chỉ định rõ thì mặc định là AFTER, FOR chỉ là từ khĩa tương thích ngược với các phiên bản trước của SQL Server.
INSTEAD OF triggers: Trigger này chỉ cĩ trong SQL Server 2000. Trigger này sẽ thi hành thay cho các câu lệnh Insert, Delete, Update. Như vậy khi tạo trigger kiểu này bạn phải viết lại các lệnh insert, Delete, Update đối với dữ liệu. Cĩ thể áp dụng cho cả bảng và View, tuy nhiên nĩ khơng cho phép áp dụng với các view cĩ lựa chọn WITH CHECK OPTION.
Nested trigger: cĩ nghĩa là bảng Table1 cĩ trigger, Table2 cĩ trigger khác. Nếu ta thao tác trên Table1 thì trigger của nĩ sẽ thực thi, nếu thao tác này cĩ liên quan đến Table2 thì trigger2 ở bảng Table2 thực thi. Gọi là lồng các trigger, bạn cĩ thể lồng tối đa là 32 cấp.
14.2 Tạo và quản lý các trigger
Một trigger cĩ thể tạo và quản lý bằng cách sử dụng Query Analyzer hoặc Enterprice Manager. Tạo một trigger trên đối tượng thì phải cĩ quyền Owner đối với đối tượng.
14.2.1 Tạo trigger
CREATE TRIGGER trigger_name
ON { table | view } [ WITH ENCRYPTION ] {
{ { FOR | AFTER | INSTEAD OF } { [DELETE] [,] [ INSERT ] [, ] [ UPDATE ] } [ WITH APPEND ]
[ NOT FOR REPLICATION ] AS
sql_statement [ ...n ] }
}
Giải thích:
- trigger_name : Tên của trigger. Nếu trong 1 bảng cĩ nhiều trigger thì tên của
các trigger phải là duy nhất.
- ON { table | view }: Chỉ định table/View được áp dụng trigger, chỉ cĩ instead of được áp dụng cho cả view và table.
- [ WITH ENCRYPTION ]: Trigger được mã hĩa. Thơng tin mã hĩa năm trong bảng syscomment
- { FOR | AFTER | INSTEAD OF }: Xác định loại trigger cho thao tác DELETE, INSERT, UPDATE.
Delete trigger: trigger sẽ được thực thi khi cĩ mẫu tin bị xĩa khỏi bảng, SQL Server tạo ra bảng mang tên DELETED để cất mẫu tin bị xĩa, trong trigger ta cĩ thể tham khảo đến mẫu tin này.
Insert trigger: trigger sẽ được thực thi khi cĩ mẫu tin chèn vào bảng, SQL server tạo ra bảng mang tên INSERTED để cất mẫu tin chèn, trong trigger ta cĩ thể tham khảo đến mẫu tin này.
Update trigger: Mỗi khi cĩ mẫu tin nào đĩ được cập nhật, giá trị những cột cĩ liên quan đến trigger sẽ được kiểm tra trước khi cập nhật. Mẫu tin bị cập nhật sẽ được sao lưu trong bảng Inserted (chứa giá trị mới) và Deleted (chứa giá trị cũ).
- [ NOT FOR REPLICATION ]: Trigger sẽ khơng thực hiện khi bảng cĩ liên quan đến kỹ thuật sao chép nhân bản (relication)
Lưu ý:
Một hành động (Insert hoặc Delete hoặc Update) cĩ thể kích hoạt cùng lúc nhiều trigger khác nhau.
Trigger sẽ thi hành cho dù thao tác của người sử dụng cĩ tác động thực sự trên các mẫu tin hay khơng, do đĩ dùng @@ROWCOUNT để kiểm tra trước khi cho các hành động trong trigger thi hành.
Các phát biểu sau khơng thể cĩ trong trigger: các phát biểu Create, Drop, Alter Table, Alter DataBase, Truncate Table, Grant/Revoke, Reconfigure, Load DataBase, Transaction, Update statistics, Select Into, Disk.
14.2.2 Quản lý trigger
Alter Trigger 2 Hiệu chỉnh trigger
Drop Trigger : Xĩa trigger
Sp_rename : đổi tên.
Sp_helptrigger, Sp_heltext: Xem code trigger
DISABLE TRIGGER/ ENABLE TRIGGER trong câu lệnh Alter Table
14.3 Vài ví dụ về trigger.
Ví dụ 1: Viết một trigger cho thao tác Insert, điểm kiểm tra ngày lập hố đơn thì luơn luơn lớn hơn ngày giao.
CREATE TRIGGER Trg_NgayLap_NgayGiaoHD ON Hoadon AFTER INSERT
AS
DECLARE @NgayLapHD DateTime, @NgayGiao DateTime
SELECT @NgayLapHD=hd.NGayLapHD,NgayGiao=hd.NgayGiaoNhan FROM HoaDon hd INNER JOIN Inserted i ON hd.MaHD=i.Mahd If @NgayGiao<@NgayLapHD
BEGIN
RAISERROR(500103,10,1) 2 Tham thảo cú pháp lệnh trong Books-Online
ROLLBACK TRANSACTION END
---
INSERT HoaDon VALUES (1003,'1/1/2004','N','TP. HCM',111,‘12/24/2003‘)
Ví dụ 2: Tạo một trigger cĩ tên là Msg_InstUpd_Kh, trigger này thực hiện chi 2 thao tác Insert, Update của bảng KhachHang. Trigger sẽ thơng báo “Cĩ n dong da duoc hieu chinh”.
Use SalesDB GO
CREATE TRIGGER Msg_InstUpd_Kh On KhachHang
FOR INSERT, UPDATE AS
RAISEORROR(‘”Cĩ %d dịng đã được hiệu chỉnh””, 0,1,@@Rowcount)
RETURN
Kiểm chứng: bằng cách chèn hoặc cập nhật 1 hoặc nhiều mẫu tin vào bảng KhachHang.
INSERT INTO KhachHang …..
Ví dụ 3: Hai bảng HoaDon và CT_HoaDon cĩ quan hệ 1-n, tức là khi thêm một chi tiết hĩa đơn trong bảng chi tiết hố đơn thì hĩa đơn này phải đã được phát sinh trong bảng hĩa đơn. Vì thế ta phải viết một trigger Insert cho bảng CT_HoaDon. Nếu ta cĩ trigger này thì khi ta vi phạm SQL Server cũng sẽ báo lỗi vì vi phạm ràng buộc tồn vẹn khĩa ngoại. Tuy nhiên ta hãy viết một trigger để thực hiện thơng bao khi cĩ lỗi này xuất hiện.
Use SalesDB GO
CREATE TRIGGER Trigger_Ins_CT_HD ON HoaDon
FOR INSERT
/* Insert trigger cho bảng hĩa đơn*/ AS
IF NOT EXISTS
(Select * From Inserted I inner join HoaDon hd ON i.Mahd = hd.Mahd)
/* Nếu Mahd được chèn vào bảng CT_HoaDon khơng tồn tại trong bảng hĩa đơn thì khơng chèn được */
RAISERROR(60000,16,1,'MaHd', 'CT_HoaDon','Mahd','Hoa Don')
ROLLBACK END
Ví dụ 4: Price trong CT_HoaDon luơn luơn lớn hơn hay bằng GiaGoc trong bảng sản phẩm. Để bắt ràng buộc này bạn thường dùng Check Constraints, tuy nhiên bạn cũng cĩ thể bẩy lỗi bằng trigger
Create Trigger MGT_Gia ON CT_HoaDon
FOR UPDATE AS
IF EXISTS (Select * From INSERTED I where i.price < tblItem.OriginalPrice)
Begin
RAISERROR(‘Khong thể cập nhật vì giá khơng hợp lệ’,16,1)
ROLLBACK TRAN End
BÀI 15: BẢO MẬT TRONG SQL SERVER