csdl3_trigger

Màu nền
Font chữ
Font size
Chiều cao dòng

5. By li (Trigger) trong SQL Server

Trigger là một dạng đặc biệt của thủ tục thường trú, được thực thi một cách tự

động khi có sự thay đổi dữ liệu (do tác động của câu lệnh INSER T, UPDATE,

DELETE) trên một bảng nào đó.

5.1 Các đặc đim ca trigger

Trigger chỉ thực thi tự động thông qua các sự kiện mà không thực hiện bằng

tay. Trigger sử dụng được với khung nhìn.

Khi trigger thực thi theo các sự kiện Insert hoặc Delete thì dữ liệu khi thay đổi

sẽ được chuyển sang các bảng INSERTED và DELETED, là 2 bảng tạm thời chỉ chứa

trong bộ nhớ, các bảng này chỉ được sử dụng với các lệnh trong trigger. Các bảng này

thường được sử dụng để khôi phục lại phần dữ liệu đã thay đổi (roll back).

Trigger chia thành 2 loại INSTEAD OF và AFTER: INSTEAD OF là loại

trigger mà hoạt động của sự kiện gọi trigger sẽ bị bỏ qua và thay vào đó là các lệnh

trong trigger được thực hiện. AFTER trigger là loại ngầm định, khác với loại

INSTEAD OF thì loại trigger này sẽ thực hiện các lệnh bênh trong sau khi đã thực

hiện xong sự kiện kích hoạt trigger.

5.2 Các trường hp s dng trigger

Sử dụng Trigger khi các biện pháp bảo đảm toàn vẹn dữ liệu khác không bảo

đảm được. Các công cụ này sẽ thực hiện kiểm tra tính toán vẹn trước khi đưa dữ liệu vào

CSDL, còn Trigger thực hiện kiểm tra tính toàn vẹn khi công việc đã thực hiện.

Khi CSDL chưa được chuNn hóa (Normalization) thì có thể xảy ra dữ liệu thừa,

chứa ở nhiều vị trí trong CSDL thì yêu cầu đặt ra là dữ liệu cần cập nhật thống nhất

trong mọi nơi. Trong trường hợp này ta phải sử dụng Trigger.

Khi xảy ra thay đổi dây chuyền dữ liệu giữa các bảng với nhau (khi dữ liệu

bảng này thay đổi thì dữ liệu trong bảng khác cũng được thay đổi theo).

5.3 Kh năng sau ca trigger

Một trigger có thể nhận biết, ngăn chặn và huỷ bỏ được những thao tác làm

thay đổi trái phép dữ liệu trong cơ sở dữ liệu.

Các thao tác trên dữ liệu (xoá, cập nhật và bổ sung) có thể đ ược trigger phát

hiện ra và tự động thực hiện một loạt các thao tác khác trên cơ sở dữ liệu nhằm đảm

bảo tính hợp lệ của dữ liệu.

Thông qua trigger, ta có thể tạo và kiểm tra được những mối quan hệ phức tạp

hơn giữa các bảng trong cơ sở dữ liệu mà bản thân các ràng buộc không thể thực hiện

được.

5.4 Định nghĩa trigger

Câu lệnh CREATE TRIGGER được sử dụng để đinh nghĩa trigger và có cấu

trúc như sau:

CREATE TRIGGER tên_trigger

ON tên_bng

FOR {[INSERT][,][UPDATE][,][DELETE]}

AS

[IF UPDATE(tên_ct)

[AND UPDATE(tên_ct)|OR UPDATE(tên_ct)]

...]

các_câu_lnh_ca_trigger

Lưu ý: Như đã nói ở trên, chuNn SQL định nghĩa hai bảng logic INSERTED và

DELETED để sử dụng trong các trigger. Cấu trúc của hai bảng này tương tự như cấu

trúc của bảng mà trigger tác động. Dữ liệu trong hai bảng này tuỳ thuộc vào câu lệnh

tác động lên bảng làm kích hoạt trigger; cụ thể trong các trường hợp sau:

Khi câu lệnh DELETE được thực thi trên bảng, các dòng dữ liệu bị xoá sẽ được

sao chép vào trong bảng DELETED. Bảng INSERTED trong tr ường hợp này không

có dữ liệu.

Dữ liệu trong bảng INSERTED sẽ là dòng dữ liệu được bổ sung vào bảng gây

nên sự kích hoạt đối với trigger bằng câu lệnh INSERT. Bảng DELETED trong

trường hợp này không có dữ liệu.

Khi câu lệnh UPDATE được thực thi trên bảng, các dòng dữ liệu cũ chịu sự tác

động của câu lệnh sẽ được sao chép vào bảng DELETED, còn trong bảng INSERTED

sẽ là các dòng sau khi đã được cập nhật.

Ví dụ 1: Ví dụ dưới đây minh họa việc trigger được kích hoạt khi thêm dữ liệu

vào bảng CUSTOMERS

if exists (select name from sysobjects

go

create trigger t_CheckCustomerName

on customers

for insert

as

declare @lengthOfName int

select @lengthOfName = len(inserted.customername)

from inserted

if @lengthOfName <=1

print N'Tên không hp l'

rollback tran

go

Thêm một khách hàng mới có tên là A

insert into customers

values('A', '5/5/1978', 'True', '35 Hung Vuong')

Ví dụ 2: Ví dụ dưới đây minh họa trigger được kích hoạt khi có sự thay đổi

mang tính đây chuyền giữa các bảng.

Giả sử có CSDL như sau:

Giả sử có một khách hàng mua 10 đơn vị mặt hàng LAPTOP. Khi đó số lượng

LAPTOP trong bảng ITEMFORSALE sẽ giảm xuống còn 90. Trigger dưới đây sẽ

thực hiện công việc đó.

if exists (select name from sysobjects

where name = 't_DecreaseQuantityOf ItemForSale')

drop trigger t_DecreaseQuantityOfItemForSale

go

create trigger t_DecreaseQuantityOfItemForSale

on SALE

for insert

as

update ITEMSFORSALE

set itemsforsale.quantity = itemsforsale.quantity - inserted.salequantity

from itemsforsale inner join inserted

on itemsforsale.itemid = inserted.itemid

go

Thực hiện thêm dòng vào bảng SALE

insert into sale values( 1, 10)

Ví dụ 3: Ví dụ này minh họa cũng minh họa trigger được kích hoạt khi có sự

thay đổi mang tính dây chuyền giữa các bảng nhưng trong trường hợp này dữ liệu

thay đổi liên quan đến nhiều dòng.

Giả sử người quản lý muốn thay đổi số lượng bán mặt hàng LAPTOP trong

bãng SALE lên thêm 5 đơn vị. Như vậy từ kết quả ví dụ 2, ta thấy cần phải giảm số lượng

LAPTOP trong bảng ITEMSFORSALE xuống 10 đ ơn vị. Tuy nhiên, trong thực tế khi số

lượng các dòng trong bảng SALE rất lớn, khi đó phải sử dụng trigger:

if exists (select name from sysobjects

where name = 't_DecreaseSumQuantityOfItemForSale')

drop trigger t_DecreaseSumQuantityOfItemForSale

go

create trigger t_DecreaseSumQuantityOfItemForSale

on SALE

for update

as

if update(salequantity)

update ITEMSFORSALE

set itemsforsale.quantity = itemsforsale.quantity -

(select sum(inserted.salequantity - deleted.salequantity)

from deleted inner join inserted

on deleted.saleid = inserted.saleid

where inserted.itemid = itemsforsale.itemid)

where itemsforsale.itemid in (select inserted.itemid

from inserted)

Thực hiện cập nhật cho bảng SALE :

update sale

set salequantity = salequantity + 10

where itemid = 1

Ví dụ 4: Ví dụ này minh họa INSTEAD OF trigger. Trigger dưới đây sẽ không

cho thực hiện thao tác xóa tr ên bảng CUSTOMERS.

create trigger t_RollbackDelete

on customers

after delete

as

rollback tran

5.5 Kích hot trigger da trên s thay đổi d liu trên ct

Thay vì chỉ định một trigger được kích hoạt tr ên một bảng, ta có thể chỉ định

trigger được kích hoạt và thực hiện những thao tác cụ thể khi việc thay đổi dữ liệu chỉ

liên quan đến một số cột nhất định nào đó của cột. Trong trường hợp này, ta sử dụng

mệnh đề IF UPDATE trong trigger. IF UPDATE không s ử dụng được đối với câu

lệnh DELETE.

Trở lại ví dụ 3 trong phần định nghĩa trigger:

if exists (select name from sysobjects

where name = 't_DecreaseSumQuantityOfItemForSale')

drop trigger t_DecreaseSumQuantityOfItemForSale

go

create trigger t_DecreaseSumQuantityOfItemForSale

on SALE

for update

as

if update(salequantity)

update ITEMSFORSALE

set itemsforsale.quantity = itemsf orsale.quantity -

(select sum(inserted.salequantity - deleted.salequantity)

from deleted inner join inserted

on deleted.saleid = inserted.saleid

where inserted.itemid = itemsforsale.itemid)

where itemsforsale.itemid in (select inserted.itemi d

from inserted)

Trong ví dụ này trigger sẽ được kích hoạt khi có sự thay đổi dữ liệu trong cột

salequantity của bảng Sale. Nếu có sự thay đổi dữ liệu trên các cột khác thì trigger sẽ

không được kích hoạt.

Câu lệnh dưới đây không làm cho trigger kích hoạt.

update sale

set itemid = 3

where itemid = 2

Mệnh đề IF UPDATE có thể xuất hiện nhiều lần trong phần thân của trigger.

Khi đó, mệnh đề IF UPDATE nào đúng thì phần câu lệnh của mệnh đề đó sẽ đ ược

thực thi khi trigger được kích hoạt.

5.6 S dng trigger và Giao tác (TRANSACTION)

Khi một trigger được kích hoạt, SQL Server luôn tạo ra một giao tác theo dõi

những thay đổi do câu lệnh kích hoạt trigger hoặc do bản thân trigger gây ra. Sự theo dõi

này cho phép

CSDL quay trở lại trạng thái trước đó.

Ví dụ: Ví dụ dưới đây xây dựng trigger không cho phép nhập vào một bản ghi

trong bảng SALE khi số lượng hàng bán lớn hơn số lượng hàng thực tế còn lại trong

bảng ITEMSFORSALE

if exists (select name from sysobjects

where name = 't_CheckQuantity' and type = 'TR')

drop trigger t_CheckQuantity

go

create trigger t_CheckQuantity

on sale

for insert

as

declare @insertedQuantity decimal(18,2)

declare @currentQuantity decimal(18,2)

declare @itemid int

select @itemid = itemid from inserted

select @insertedQuantity = salequantity from inserted

select @currentQuantity = quantity

from itemsforsale

where itemid = @itemid

if(@currentquantity < @insertedquantity)

print N's lượng nhp vào ln hơn s lượng hin có'

rollback tran

Tiến hành thêm vào bảng SALE số liệu như sau:

insert into sale values(2, 1000)

5.6 DDL TRIGGER

Được giới thiệu trong SQL Server 2005, khác v ới DML trigger được kích hoạt

khi có sự thay đổi dữ liệu trên bảng, DDL trigger được thiết kế để đáp ứng lại các sự kiện

diễn ra trên server hay trên CSDL. Một DDL trigger có thể được kích hoạt khi người dùng

thực hiện các lệnh CREATE TABLE hay DROP TABLE. Ở cấp độ server, DDL trigger có

thể được kích hoạt khi có một tài khoản mới được tạo ra DDL trigger được lưu trữ trong

CSDL mà DDL trigger được gắn vào. Với các Server DDL Trigger theo dõi các thay đổi ở

cấp độ Server, được lưu trữ trong CSDL master.

DDL trigger được tạo ra cũng bằng câu lệnh CREATE TRIGGER với cấu trúc

như sau:

CREATE TRIGGER tên_trigger

ON { ALL SERVER | DATABASE }

FOR { loại_sự_kiện } [ ,...n ]

AS { các_câu_lệnh_SQL}

Trong đó:

ALL SERVER | DATABASE : quy định trigger sẽ kích hoạt dựa trên các sự

kiện diễn ra trên Server hay các sự kiện diễn ra trên CSDL.

loi_s_kin: là một sự kiện đơn ở cấp độ Server hay cấp độ CSDL làm kích

hoạt DDL trigger như: CREATE_TABLE, ALTER_TABLE, DROP_TABLE…

Ví dụ 1: Câu lệnh dưới đây xây dựng một trigger được kích hoạt khi xảy ra các

sự kiện ở cấp độ CSDL. Trigger này sẽ ngăn chặn các lệnh DROP TABLE và ALTER

TABLE.

create trigger t_safety

on database

for CREATE_TABLE, DROP_TABLE

as

print N'Phi xóa trigger t_safety trước khi ALTER hay DROP bng'

rollback tran

Tiến hành xóa bảng ORDERDETAIL

drop table orderdetail

Ví dụ 2: Câu lệnh dưới đây xây dựng một trigger được kích hoạt khi xảy ra các

sự kiện ở cấp độ Server. Trigger này sẽ ngăn chặn việc tạo ra một account login mới

IF EXISTS (SELECT * FROM sys.server_triggers

WHERE name = 't_DoNotAllowCreateNewLogin')

DROP TRIGGER t_DoNotAllowCreateNewLogin

ON ALL SERVER

GO

CREATE TRIGGER t_DoNotAllowCreat eNewLogin

ON ALL SERVER

FOR CREATE_LOGIN

AS

PRINT N'Phi DROP trigger t_DoNotAllowCreateNewLogin tr ước khi

to account'

rollback

GO

Tiến hành tạo một account login mới :

create login test with password = '123456'

5.7 Enable/ Disable TRIGGER

Trigger cần bị vô hiệu hóa trong một số trường hợp:

Trigger gây ra lỗi trong quá trình xử lý CSDL

Quá trình nhập hay khôi phục những dữ liệu không thỏa trigger.

Vô hiệu hóa trigger bằng lệnh DISABLE TRIGGER có cấu trúc như sau:

DISABLE TRIGGER tên_trigger

ON { tên_đối_tượng | DATABASE | SERVER }

Ví dụ 1: Ví dụ này sẽ vô hiệu hóa trigger t_DoNotAllowCreateNewLogin

disable trigger t_DoNotAllowCreateNewLogin

on all server

Tiến hành tạo một account login mới:

create login newLogin with password = '12345'

Ví dụ 2: Ví dụ này sẽ khôi phục lại trigger t_ DoNotAllowCreateNewLogin

enable trigger t_DoNotAllowCreateNewLogin

on all server

Tiến hành tạo một account login mới:

create login newLogin1 with password = '12345'

Bạn đang đọc truyện trên: Truyen2U.Pro