Trigger là một loại stored-proc đặc biệt, tự động thực thi khi một sự kiện diễn ra trong cơ sở dữ liệu ở server. Trigger được định nghĩa trên 1 bảng hay 1 view cụ thể.. DDL Trigger
Trang 4 Trigger là một loại stored-proc đặc biệt, tự động thực thi khi một sự kiện diễn ra trong cơ sở dữ liệu ở server.
Trigger được định nghĩa trên 1 bảng hay 1 view cụ thể.
Trigger thường được dùng khi cần đảm bảo tính toàn vẹn dữ liệu phức tạp mà các ràng buộc khác như Check, Assertion khó đạt được, với sự vượt trội về tính đúng đắn cao hơn Check và sự linh hoạt nhiều hơn Assertion.
Trang 5 DML Trigger : thực thi khi dữ liệu bị thay đổi bởi
1 sự kiện DML thông qua các câu lệnh T-SQL INSERT, UPDATE, DELETE trên 1 bảng hay view Thường được sử dụng trong thực tiễn để hiện thực các quy định…
› Ví dụ: Trigger xuất ra 1 thông báo mỗi khi có một hóa đơn được lập…
Trang 6 DDL Trigger : thực thi khi có các sự kiện DDL
xảy ra trong cơ sở dữ liệu hay trên server, được gây ra bởi các câu lệnh T-SQL như CREATE,
ALTER, DROP hay 1 số stored-proc hệ thống
Thường được sử dụng trong thực tiễn để kiểm tra, quản lý các thao tác được phép lên các đối tượng trên hệ thống.
› Ví dụ: Trigger ngăn không cho phép DROP table nào trong hệ thống…
Trang 7 Logon Trigger : thực thi khi 1 session của
user đã được thiết lập, xác thực, và gọi sự kiện LOGON.
› Ví dụ: Trigger giới hạn số session của cùng
một LoginID, cùng lúc đăng nhập vào hệ thống là 2 Nếu vượt số này, các đăng nhập sau sẽ bị từ chối…
Trang 8 SQL Server thiết lập 2 bảng tạm ảo trong lúc 1
DML Trigger đang thực thi, đó là Inserted và Deleted.
Các bảng này chứa các dòng mới thêm vào
(Inserted) hoặc đã bị xóa (Deleted) của bảng của trigger, lúc trigger khởi chạy Các bảng này có cấu trúc như bảng của trigger.
Trang 9Câu lệnh
DML
Bảng tạm ảo Inserted
Bảng tạm ảo Deleted
Insert Các dòng mới thêm
Trang 10 Thực thi khi dữ liệu bị thay đổi bởi 1 sự kiện
DML thông qua các câu lệnh T-SQL INSERT, UPDATE, DELETE trên 1 bảng hay view.
thay thế sự kiện đó bằng hành động khác.
tạm ảo là Inserted và Deleted (đã đề cập).
Trang 11Cú pháp:
Trang 12Các tham số:
[tên_schema.]tên_trigger : tham số bắt buộc, là tên của
schema mà bảng của DML trigger nằm trong schema đó.
› Ví dụ: dbo.trXemThongTinBangDeleted…
tên_bảng hoặc tên_view : tham số bắt buộc, là tên bảng
hoặc view mà DML trigger được gọi thực thi View chỉ cho phép đối với các trigger Instead Of.
WITH ENCRYPTION : tham số tùy ý, là lựa chọn mã hóa dữ
liệu của trigger Khi đó, không thể xem nội dung của trigger
bằng sp_helptext
› Chú ý: không dùng chung với tham số EXTERNAL NAME
Trang 13Ví dụ WITH ENCRYPTION :
Trigger DML lúc chưa mã hóa, vẫn xem được nội dung bằng
sp_helptext :
Trang 14Ví dụ WITH ENCRYPTION :
Trigger DML lúc đã mã hóa :
Trang 15Các tham số (tt):
FOR hoặc AFTER : tham số bắt buộc, không thể tạo
trên view Trigger khởi chạy khi các thao tác của sự kiện DML đã thực hiện thành công (dù kết quả không có bản ghi(dòng) nào) Lúc này, các cập nhật tham chiếu cascade và kiểm tra ràng buộc đã hoàn tất trước khi trigger khởi chạy Cho phép nhiều trigger cùng loại (Insert, Update, Delete) trên cùng 1 bảng.
INSTEAD OF : tham số bắt buộc, có thể được tạo trên 1
view Trigger khởi chạy trước các hành động của sự kiện DML, và thay thế các hành động không cho chúng thực hiện Chỉ cho phép 1 trigger mỗi loại (Insert, Update, Delete) trên cùng 1 bảng hay 1 view.
Trang 16Ví dụ AFTER:
› Tạo 2 trigger cùng loại Delete trên cùng bảng KhachHang: 1 trigger xem thông tin đã bị xóa, và 1 trigger hiển thị thông báo đã xóa.
Trang 17Ví dụ INSTEAD OF:
› Không cho phép tạo nhiều hơn 1 trigger Instead Of trên cùng 1 bảng KhachHang
Trang 18Các tham số (tt):
INSERT, UPDATE, DELETE : tham số bắt buộc, có thể thiết
lập đồng thời nhiều loại thao tác DML này.
WITH APPEND : tham số tùy ý, không thể sử dụng chung với
Instead Of hay After, hoặc có tham số EXTERNAL NAME Tham số này chỉ được sử dụng khi thiết lập tương thích của CSDL là thấp hơn 65 (nghĩa là SQL Server các phiên bản trước 2000(70) ) Tham số cho biết trigger này được thêm vào khi đã có trigger cùng loại tồn tại trên bảng của trigger.
NOT FOR REPLICATION : tham số tùy ý, chỉ định việc trigger
không thực thi khi có một tác nhân bản sao đang thay đổi bảng của trigger bằng các câu lệnh DML.
Trang 19Ví dụ NOT FOR REPLICATION :
› Để lưu vết khi quản lý khi INSERT vào bảng HOADON,
ta viết 1 INSERT Trigger có FOR NOT REPLICATION mỗi khi INSERT một chi tiết hóa đơn thì ta thêm dòng đó vào một bảng lưu vết, giả sử là bảng LuuVet_HoaDon Khi đó, mọi user khi INSERT ở bảng này thì Trigger sẽ thực thi INSERT thêm vào bảng LuuVet_HoaDon Tuy nhiên, khi tạo bản sao gửi cho các đăng kí khác của CSDL, nếu ở các bản sao này xảy ra INSERT thì Trigger
sẽ không khởi chạy, không thêm vào bảng LuuVet_HoaDon.
Trang 20Các tham số (tt):
Các_câu_lệnh_SQL : tham số bắt buộc Đây là các câu
lệnh SQL mang điều kiện và các xử lý của trigger Những câu lệnh này quyết định xử lý của trigger đối với các sự kiện DML thao tác lên bảng/view của trigger Hỗ trợ hầu hết các câu lệnh như stored-procedure…
› Ví dụ: Tạo biến @TienNo, gán giá trị cho biến là tiền nợ của khách hàng mới Insert vào bảng KhachHang rồi in
ra giá trị của biến @TienNo sau khi đã chuyển kiểu của biến về kiểu chuỗi kí tự
Trang 21Ví dụ:
Trang 22Các tham số (tt):
EXTERNAL NAME chú_thích_của_phương_thức : tham
số bắt buộc đối với các trigger viết bởi CLR (Common Language Runtime), được tạo ra từ các phương thức của các assembly trong NET Framework… Tham số có dạng tên_assembly.tên_class.tên_phương thức.
›Ví dụ: Ta đã dùng VB.NET để viết 1 thư viện CLRTrigger_KhachHang.dll,
có chứa class CLRTriggers Trong class này có phương thức
tr_InsertKhachHang dùng để xử lý khi có sự kiện Insert trong bảng
KhachHang Lúc đó, ta tích hợp thư viện này vào SQL Server dưới dạng 1 assembly, và tạo 1 trigger CLR từ assembly này
Trang 23Ví dụ EXTERNAL NAME :
Trang 24Ví dụ :
Tạo Trigger trThemKhachHang_After để kiểm tra khách hàng mới tạo thêm có tiền nợ có bằng 0 Nếu thỏa, thực hiện tạo mới Nếu
không thỏa, không cho tạo mới
Tạo trigger và nhập khách hàng mới có tiền nợ là 100 :
Trang 25Ví dụ (tt):
Nhập khách hàng mới có mã là KH1007 và có tiền nợ là 0 :
Trang 26 Thực thi khi dữ liệu bị thay đổi bởi 1 sự kiện DDL thông qua các câu lệnh T-SQL CREATE, ALTER, DROP, GRANT, DENY, REVOKE, hay UPDATE STATISTICS trên 1 cơ sở dữ liệu hay toàn hệ thống, chứ không phụ thuộc schema như trigger DML.
Một số stored-proc hệ thống có các thao tác DDL nên
có thể khởi chạy các trigger DDL.
› Ví dụ: câu lệnh CREATE TYPE và stored-proc sp_addtype sẽ
khởi chạy trigger DDL được định nghĩa trên sự kiện CREATE_TYPE
Chỉ có thể được gọi sau khi sự kiện hoàn tất (không hỗ trợ INSTEAD OF).
Trang 27Cú pháp:
Trang 28Các tham số:
tên_trigger : tham số bắt buộc, là tên của trigger, phải
theo đúng các quy định về định danh của T-SQL.
ALL SERVER | DATABASE: tham số bắt buộc, chỉ định
phạm vi tác dụng của trigger, nếu ALL SERVER thì phạm vi toàn hệ thống (System Triggers), còn DATABASE thì chỉ phạm vi trong cơ sở dữ liệu hiện tại (Database Triggers).
› Ví dụ: Khi tạo 1 trigger DDL phạm vi toàn hệ thống, trigger sẽ được xem là một Server Object và được lưu trữ ở thư mục Server Triggers :
Trang 29 Trigger ALL SERVER :
Trigger đã tạo được lưu trữ như 1 Server Object :
Ví dụ ALL SERVER:
Trang 30Các tham số (tt):
WITH ENCRYPTION : tham số tùy ý, là lựa chọn mã hóa dữ
liệu của trigger Khi đó, không thể xem nội dung của trigger
bằng sp_helptext
› Chú ý: không dùng chung với tham số EXTERNAL NAME
FOR hoặc AFTER : tham số bắt buộc, không thể tạo trên
view Trigger khởi chạy khi các thao tác của sự kiện DDL đã thực hiện thành công.
Sự_kiện_DDL | nhóm_sự_kiện_DDL : tham số bắt buộc, có
thể là CREATE, ALTER, DROP, GRANT, DENY, REVOKE, hay UPDATE STATISTICS trên 1 cơ sở dữ liệu hay toàn hệ thống Bên cạnh đó, có các nhóm_sự_kiện_DDL đã định sẵn như nhóm sự kiện trên bảng DDL_TABLE_EVENTS, nhóm
sự kiện trên các phiên đăng nhập DDL_LOGIN_EVENTS…
Trang 31 các_câu_lệnh_SQL : tham số bắt buộc Đây là các câu lệnh
SQL mang điều kiện và các xử lý của trigger Những câu lệnh này quyết định xử lý của trigger đối với các sự kiện DDL thao tác lên các đối tượng của hệ thống Hỗ trợ hầu hết các câu lệnh như stored-procedure…
EXTERNAL NAME chú_thích_của_phương_thức : tham
số bắt buộc đối với các trigger viết bởi CLR (Common Language Runtime), được tạo ra từ các phương thức của
Tham số có dạng tên_assembly.tên_class.tên_phương thức
Trang 32Ví dụ :
› Tạo 1 trigger ngăn không cho CREATE và DROP TABLE trên cơ sở
dữ liệu master:
Trang 33Ví dụ (tt):
Khi thực hiện xóa bảng Gupta của bảng master thì :
Trang 34 Thực thi khi 1 session của user đã được thiết lập, xác thực, và gọi sự kiện LOGON.
Cú pháp:
Trang 35Các tham số:
tên_trigger : tham số bắt buộc, là tên của trigger, phải theo
đúng các quy định về định danh của T-SQL.
WITH ENCRYPTION : tham số tùy ý, là lựa chọn mã hóa dữ
liệu của trigger Khi đó, không thể xem nội dung của trigger
bằng sp_helptext
› Chú ý: không dùng chung với tham số EXTERNAL NAME
FOR hoặc AFTER : tham số bắt buộc, không thể tạo trên
view Trigger khởi chạy khi các thao tác của sự kiện LOGON
đã thực hiện thành công, nghĩa là đăng nhập đã được xác thực nhưng chưa thiết lập phiên làm việc cho đăng nhập đó.
Trang 36Các tham số (tt):
các_câu_lệnh_SQL : tham số bắt buộc Đây là các câu
lệnh SQL mang điều kiện và các xử lý của trigger Những câu lệnh này quyết định xử lý của trigger đối với các sự kiện LOGON của hệ thống Hỗ trợ hầu hết các câu lệnh như stored-procedure…
EXTERNAL NAME chú_thích_của_phương_thức :
tham số bắt buộc đối với các trigger viết bởi CLR (Common Language Runtime), được tạo ra từ các phương thức của các assembly trong NET Framework… Tham số có dạng tên_assembly.tên_class.tên_phương thức.
Trang 37 Dùng để thay đổi nội dung của các trigger DML, DDL hay LOGON
đã được tạo bằng CREATE TRIGGER
Cú pháp:
Trang 38 Dùng để loại bỏ 1 hay nhiều trigger DML, DDL hay LOGON đã được tạo bằng CREATE TRIGGER.
Cú pháp:
Trang 40Cursor là một thành phần của cơ sở dữ liệu (CSDL)
sử dụng để truy xuất dữ liệu theo từng hàng Với cursor, ta có thể chọn ra một record bất kỳ trong một tập hợp các dòng dữ liệu nào đó bằng cách di chuyển
vị trí của cursor trong bảng
Nếu giải thích một cách ngắn gọn thì cursor tương
tự như recordset hay dataset trong programming Nghĩa là ta select một số data vào memory sau đó có thể lần lượt làm việc với từng record bằng cách Move Next
Trang 42 SQL Server có 3 loại cursors là Transact- SQL
Cursors, API Cursors và Client Cursors Trong đó Transact-SQL và API thuộc loại Server Cursors nghĩa
là cursors được load lên và làm việc bên phía server
Transact-SQL Cursors: Ta thường dùng
Transact-SQL cursors với Transact-SQL, điển hình là trong stored procedure hoặc trong một chuỗi lệnh xử lý từng dòng (a batch that needs to do row-by-row processing) Loại cursor này sử dụng các câu lệnh quen thuộc như DECLARE, OPEN, FETCH sẽ được đề cập ở phần dưới Dạng cursor này cho phép xét theo hướng lùi hoặc tới bất kỳ dòng nào trong kết quả.
Trang 43 API Server Cursors: OLE DB provider, ODBC driver của SQL Server và thư viện lập trình DB-Library có những cursor đặc biệt được tối ưu hóa để
sử dụng tốt hơn trong mạng lưới giữa server và client Đối với những ứng dụng high-performance, lưu lượng thông tin truyền giữa client và server là rất quan trọng Nếu ứng với mỗi dòng được FETCH đều gửi 1 lệnh độc lập đến server (như trong T-SQL cursor) thì sẽ phát sinh một lượng thông tin khổng lồ phải trao đổi.
Để hỗ trợ cho việc giao tiếp client-server, loại cursor này có một số tính năng dặc biệt mà T-SQL không có:
Cursor này có thể trỏ cùng lúc nhiều dòng dữ liệu (T-SQL chỉ trỏ được 1 dòng duy nhất) Và “độ mập” của cursor (số dòng cursor có thể trỏ) sẽ được người dùng quy định.
Để tối ưu tốc độ, “metadata” sẽ chỉ được gửi một lần duy nhất (chứ không phải được gửi mỗi lần fetch như T-SQL cursor)
API server curser có thể được khai báo trong SP ngay cả khi SP chỉ chứa duy nhất 1 câu lệnh SELECT
Trang 44 Client Cursors : ODBC cung cấp một dạng cursor được thi hành ngay tại client (chứ không thi hành trên server như 2 lọai trên) Với client cursor, các tập kết quả cũng như các cursor đã thi hành sẽ được lưu cache lại tại client (thông qua một tập kết quả mặc định nào đó) Cursor này chỉ hỗ trợ “forward-only” và Client cursor chỉ được dùng để tránh một số hạn chế của server cursor như việc không hỗ trợ tất cả các câu lệnh T-SQL (If a static scrolling cursor is needed on a Transact-SQL statement or batch that cannot be executed with a server cursor, consider using a client cursor.)
Trang 45 Transact-SQL cursors được tạo ra trên server bằng các câu lệnh Transact-SQL và chủ yếu được dùng trong
stored procedures và triggers Trước hết hãy xem qua một ví dụ đơn giản về cursor:
› Trong ví dụ sau, trước khi dùng cursor ta DECLARE
biến @au_fname và @au_lname để chứa các giá trị lấy được từ cursor Sau đó, ta SELECT LastName
và FirstName từ Employees table của Northwind database và load vào Employee_Cursor Cuối cùng, lần lượt in tên của các employee ra màn hình.
Trang 47 Các bước làm việc với cursor:
Bước 1: Khai báo cursor
Cú pháp:
DECLARE cursor_name CURSOR
[LOCAL | GLOBAL]
[FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC | FAST_FORWARD]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
[TYPE_WARNING]
Dùng câu lệnh DECLARE CURSOR để khai báo một cursor
Có thể khai báo thêm các thuộc tính của cursor (optional)
Khi khai báo ta cũng phải cho biết câu lệnh SELECT (sau FOR) sẽ được thực hiện để lấy data cho cursor Hầu hết những hệ cơ sở
dữ liệu chỉ cho phép cursor đi một chiều tiến lên Nhưng SQL Server cho phép cursor có thể di chuyển vị trí và thao tác trên bất
kỳ dòng nào
Trang 48 Nếu GLOBAL không được khai báo và tồn tại cả 2 cursor GLOBAL
và LOCAL thì cursor LOCAL sẽ được OPEN Ngược lại, cursor
GLOBAL sẽ được OPEN
Sau khi cursor được OPEN, ta có thể xác định số dòng kết quả
được tìm thấy bởi cursor này bằng: @@CURSOR_ROWS (scalar function)
Trang 49 Bước 3: Hiển thị một cursor
Thông thường ta FETCH data trước sau đó loop cho tới record cuối của Cursor bằng vòng lặp WHILE bằng cách kiểm tra global variable
@@FETCH_STATUS (=0 nghĩa là thành công)
Trang 50 Bước 4: Thao tác với record hiện hành
Khi nhảy tới mỗi record ta có thể thao tác với record đó theo ý mình.
Sử dụng các lệnh T-SQL thông thường như PRINT,
UPDATE, DELETE…
Ví dụ:
UPDATE table SET column = value
WHERE CURRENT OF cursor_name DELETE table WHERE CURRENT OF cursor_name
Trang 51 Khi DEALLOCATE 1 cursor thì sẽ xóa hoàn toàn các phép tham chiếu đến nó.
Trang 52Các thuộc tính của cursor:
cursor_name: tên của cursor, chứa từ 1-128 ký tự
cursor_variable_name: tên của biến cursor tham chiếu đến 1 cursor
select_statement: các câu lệnh select cơ bản, không chứa các lệnh COMPUTE, COMPUTE BY, FOR BROWSE anh từ khóa INTO
READ_ONLY: Cursor chỉ đọc Thuộc tính READ_ONLY không cho phép bạn “edit” record Do đó chương trình trên sẽ báo lỗi