Tạo trình kích hoạt trong máy chủ sql. Kích hoạt: tạo và sử dụng

Tổng quan về trình kích hoạt Trình kích hoạt Trình kích hoạt DML Trình kích hoạt DDL Sự kiện DML: Chèn, Xóa, Cập nhật đăng nhập Kích hoạt Sự kiện DDL: Tạo, Thả, Thay đổi Đăng nhập được giới thiệu trong SQL Server 2005

DML - Đối tượng kích hoạt - bảng, Sự kiện XEM - chèn, cập nhật, xóa cho bảng và cho VIEW. Thời gian kích hoạt – trước (thay vì) hoặc sau khi thực hiện câu lệnh.

Trình kích hoạt DML Trình kích hoạt là một khối được thực thi tự động mỗi khi một sự kiện nhất định xảy ra - trái ngược với một thủ tục, phải được gọi rõ ràng Sự kiện - CHÈN, CẬP NHẬT và XÓA cho một bảng, dạng xem - không thể xác định trình kích hoạt cho một truy vấn

Trình kích hoạt DML Trình kích hoạt được tạo trên một bảng cơ sở dữ liệu, nó cũng có thể truy cập các bảng và đối tượng khác của cơ sở dữ liệu khác. Không thể tạo trình kích hoạt trên các bảng tạm thời hoặc bảng hệ thống mà chỉ trên các bảng hoặc dạng xem do người dùng xác định. Bảng mà trigger được xác định được gọi là bảng trigger.

Khi nào cần kích hoạt Để đánh giá trạng thái của bảng trước và sau khi dữ liệu thay đổi và thực hiện hành động dựa trên sự khác biệt đó. Nhiều trình kích hoạt DML cùng loại (CHÈN, CẬP NHẬT hoặc XÓA) trên một bảng cho phép bạn thực hiện nhiều hành động khác nhau để phản hồi lại một câu lệnh sửa đổi dữ liệu.

Khi cần kích hoạt Để thay đổi xếp tầng trong các bảng cơ sở dữ liệu liên quan (nếu chúng không thể được thực hiện bằng cách sử dụng các ràng buộc toàn vẹn tham chiếu xếp tầng). Để ngăn chặn các hoạt động CHÈN, CẬP NHẬT và XÓA vô tình hoặc không chính xác Để thực hiện các ràng buộc toàn vẹn không thể được chỉ định bằng cách sử dụng ràng buộc KIỂM TRA. Trình kích hoạt DML có thể tham chiếu các cột của các bảng khác.

Thêm... Ghi nhật ký và kiểm tra. Bằng cách sử dụng trình kích hoạt, bạn có thể theo dõi các thay đổi đối với các bảng yêu cầu hỗ trợ bảo mật nâng cao. Dữ liệu thay đổi bảng có thể được lưu trữ trong các bảng khác và bao gồm, ví dụ: ID người dùng, thời gian thao tác cập nhật; bản thân dữ liệu được cập nhật, v.v. Đối chiếu và làm sạch dữ liệu. Bất kỳ câu lệnh SQL đơn giản nào cập nhật một bảng đều có thể được liên kết với các trình kích hoạt thực hiện cập nhật tương ứng trên các bảng khác. Các hoạt động không liên quan đến sửa đổi cơ sở dữ liệu. Trình kích hoạt có thể thực hiện nhiều thao tác hơn là chỉ cập nhật cơ sở dữ liệu. Tiêu chuẩn SQL cho phép bạn xác định các thủ tục được lưu trữ (có thể được gọi từ trình kích hoạt) để gửi email, in tài liệu, v.v.

Khi nào bạn không nên sử dụng trình kích hoạt Bạn không cần triển khai với trình kích hoạt những khả năng đạt được bằng cách sử dụng các công cụ khai báo DBMS (ràng buộc toàn vẹn hoặc khóa ngoại) Tránh các chuỗi trình kích hoạt phức tạp

Lời khuyên Không sử dụng trigger khi bạn có thể sử dụng ràng buộc CHECK Không sử dụng ràng buộc CHECK khi bạn có thể sử dụng ràng buộc UNIQUE.

Các tham số kích hoạt cơ bản Tên bảng (hoặc dạng xem) Thời gian kích hoạt: SAU(FOR) hoặc INSTEAD OF Sự kiện: CHÈN, CẬP NHẬT, XÓA (BẢNG TRUNCATE không phải là xóa!) Nội dung kích hoạt! Trình tự trigger cùng loại là tùy ý

Nhóm các sự kiện Ví dụ: bạn có thể tạo một trình kích hoạt kích hoạt khi một câu lệnh UPDATE hoặc INSERT được thực thi, mà chúng ta sẽ gọi là trình kích hoạt UPDATE/INSERT. Bạn thậm chí có thể tạo trình kích hoạt sẽ kích hoạt khi xảy ra bất kỳ sự kiện nào trong số ba sự kiện sửa đổi dữ liệu (trình kích hoạt CẬP NHẬT/CHÈN/XÓA).

Quy tắc kích hoạt Trình kích hoạt được kích hoạt sau khi câu lệnh khiến chúng kích hoạt hoàn tất. Ví dụ: trigger UPDATE sẽ không kích hoạt cho đến khi câu lệnh UPDATE được thực thi. Nếu bất kỳ câu lệnh nào cố gắng thực hiện một thao tác vi phạm một số ràng buộc bảng hoặc gây ra một số lỗi khác thì trình kích hoạt liên quan của nó sẽ không kích hoạt.

Quy tắc kích hoạt Trình kích hoạt được coi là một phần của một giao dịch cùng với câu lệnh gọi nó. Do đó, bạn có thể gọi toán tử khôi phục từ trình kích hoạt và toán tử này sẽ khôi phục cả trình kích hoạt và sự kiện sửa đổi dữ liệu tương ứng. Nếu xảy ra lỗi trong khi thực hiện kích hoạt, toàn bộ giao dịch sẽ tự động được khôi phục. Trình kích hoạt chỉ kích hoạt một lần cho mỗi câu lệnh, ngay cả khi câu lệnh đó ảnh hưởng đến nhiều hàng dữ liệu.

Ví dụ TẠO TRIGGER trg TRÊN my_table ĐỂ CHÈN, CẬP NHẬT, XÓA NHƯ chọn "đây là trình kích hoạt"

Khi trigger được gọi, các câu lệnh SQL được chỉ định sau từ khóa AS sẽ được thực thi. Bạn có thể đặt nhiều câu lệnh ở đây, bao gồm các cấu trúc lập trình như IF và WHILE.

Việc chọn loại trình kích hoạt INSTEAD OF kích hoạt được sử dụng để: – Ngăn chặn có chọn lọc việc thực thi lệnh mà trình kích hoạt được xác định (kiểm tra điều kiện tiên quyết); – Đếm giá trị cột trước khi lệnh INSERT hoặc UPDATE hoàn thành. Kích hoạt SAU được sử dụng để: – Tính toán các hoạt động đã hoàn thành; – Kiểm tra các điều kiện sau khi thực hiện lệnh.

Vòng lặp và lồng nhau SQL Server cho phép bạn sử dụng trình kích hoạt lồng nhau, sâu tới 32 cấp độ. Nếu bất kỳ trình kích hoạt lồng nhau nào thực hiện thao tác ROLLBACK thì các trình kích hoạt tiếp theo sẽ không được kích hoạt. Kích hoạt bị hủy nếu xảy ra vòng lặp vô hạn.

INSTEAD OF Trigger Trình kích hoạt INSTEAD OF thực thi thay vì chạy câu lệnh SQL. Điều này ghi đè hành động của câu lệnh bắt đầu. Bạn có thể xác định một trigger INSTEAD OF cho mỗi câu lệnh INSERT, UPDATE hoặc DELETE. Một trình kích hoạt INSTEAD OF có thể được xác định trên một bảng và/hoặc một khung nhìn. Bạn có thể sử dụng các tầng trình kích hoạt INSTEAD OF bằng cách xác định các khung nhìn ở đầu các khung nhìn, trong đó mỗi khung nhìn có một trình kích hoạt INSTEAD OF riêng biệt. Trình kích hoạt INSTEAD OF không được phép trên các chế độ xem có thể sửa đổi có chứa tùy chọn CÓ KIỂM TRA.

SAU Bộ kích hoạt SAU Bộ kích hoạt chỉ có thể được xác định trên các bảng. Trình kích hoạt SAU kích hoạt sau khi tất cả các thao tác được chỉ định trong câu lệnh SQL kích hoạt hoặc các câu lệnh đã hoàn tất thành công. Điều này bao gồm toàn bộ chuỗi hành động liên kết và tất cả các kiểm tra ràng buộc.

SAU Trình kích hoạt Nếu bạn có nhiều trình kích hoạt SAU được xác định bởi một bảng cho một câu lệnh hoặc tập hợp các câu lệnh cụ thể, bạn có thể chỉ định trình kích hoạt nào sẽ kích hoạt đầu tiên và trình kích hoạt nào sẽ kích hoạt cuối cùng. Nếu bạn có nhiều hơn hai trình kích hoạt được xác định, bạn có thể chỉ định thứ tự kích hoạt của trình kích hoạt đầu tiên và cuối cùng. Tất cả các kích hoạt khác được kích hoạt ngẫu nhiên.

SAU Lệnh kích hoạt sp_settriggerorder @triggername = "Another. Trigger", @order = "first" sp_settriggerorder @triggername = "My. Trigger", @order = "last" sp_settriggerorder @triggername = "My.Other.Trigger", @order = "none" sp_settriggerorder @triggername = "Còn nữa. Trigger", @order = "none"

Sử dụng các bảng đã chèn, đã xóa Các bảng đặc biệt: đã chèn – các giá trị đã chèn (đối với INSERT, UPDATE) đã xóa – các giá trị đã xóa (đối với UPDATE, DELETE)

Sử dụng các bảng đã xóa và chèn Khi tạo một trình kích hoạt, bạn có quyền truy cập vào hai bảng tạm thời có tên là đã xóa và đã chèn. Chúng được lưu trữ trong bộ nhớ, không phải trên đĩa. Hai bảng này có cấu trúc giống như bảng (cùng cột và kiểu dữ liệu) mà trình kích hoạt này được xác định trên đó.

Sử dụng các bảng đã xóa và chèn Bảng đã xóa chứa các bản sao của các hàng bị ảnh hưởng bởi câu lệnh DELETE hoặc UPDATE. Các hàng bị xóa khỏi bảng của trình kích hoạt này sẽ được chuyển đến bảng đã xóa. Dữ liệu bảng đã xóa sau đó có thể được truy cập từ trình kích hoạt này. Bảng được chèn chứa bản sao của các hàng đã được thêm vào bảng của trình kích hoạt này khi câu lệnh INSERT hoặc UPDATE được thực thi. Các hàng này được thêm đồng thời vào bảng kích hoạt và bảng được chèn.

Sử dụng các bảng đã xóa và chèn Bởi vì một câu lệnh CẬP NHẬT được xử lý dưới dạng DELETE theo sau là một INSERT, khi bạn sử dụng câu lệnh UPDATE, các giá trị hàng cũ sẽ được sao chép vào bảng đã xóa và các giá trị hàng mới sẽ được sao chép vào trình kích hoạt bảng và bảng được chèn. Trình kích hoạt INSERT => đã xóa trống. Trình kích hoạt DELETE => đã chèn trống nhưng sẽ không xuất hiện thông báo lỗi!

Tạo trình kích hoạt TẠO TRIGGER [ lược đồ_name. ]trigger_name BẬT ( bảng | xem ) ( FOR | AFTER | INSTEAD OF ) ( [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] ) NHƯ ( sql_statement )

TẠO TRIGGER plus_1 TRÊN bảng 1 thay vì chèn AS chèn bảng 1 (id, col 1) chọn id+1, col 1 từ đã chèn;

Xử lý ngoại lệ Lệnh ROLLBACK hướng dẫn máy chủ ngừng xử lý sửa đổi và không cho phép giao dịch. Ngoài ra còn có lệnh RAISEERROR mà bạn có thể sử dụng để gửi thông báo lỗi cho người dùng. CỐ GẮNG BẮT

Thông báo lỗi xử lý ngoại lệ RAISERROR ("Lỗi phát sinh do dữ liệu sai.", -- Nội dung thông báo. 16, -- Mức độ nghiêm trọng. 1 -- Trạng thái.); Mức độ nghiêm trọng - một số từ 0 đến 25 Mức độ nghiêm trọng của lỗi do người dùng xác định. Bất kỳ người dùng nào cũng có thể chỉ định từ 0 đến 18. 19 đến 25 chỉ có thể được chỉ định bởi sysadmin. 20 đến 25 được coi là nghiêm trọng - kết nối với máy khách bị mất và thông báo lỗi được ghi vào ứng dụng và nhật ký lỗi. Trạng thái Một số nguyên từ 0 đến 255. Giá trị âm hoặc giá trị lớn hơn 255 dẫn đến lỗi được tạo. Nếu cùng một lỗi tùy chỉnh xảy ra ở nhiều vị trí, bạn có thể sử dụng số trạng thái duy nhất cho từng vị trí để xác định vị trí xảy ra lỗi trong mã.

Hàm lỗi Hàm ERROR_LINE() trả về số dòng nơi xảy ra lỗi. Hàm ERROR_MESSAGE() trả về nội dung tin nhắn sẽ được trả về ứng dụng. Văn bản chứa các giá trị cho tham số thay thế như độ dài, tên đối tượng hoặc thời gian. ERROR_NUMBER() trả về số lỗi. Hàm ERROR_PROCEDURE() trả về tên của thủ tục được lưu trữ hoặc trình kích hoạt đã xảy ra lỗi. Hàm này trả về NULL nếu lỗi đã cho không được thực hiện trong quy trình hoặc trình kích hoạt được lưu trữ. ERROR_SEVERITY() trả về mức độ nghiêm trọng của lỗi. ERROR_STATE() trả về trạng thái.

Ví dụ về trình kích hoạt TẠO TRIGGER Thấp. Tín dụng TRÊN Mua hàng. Mua. Đặt hàng. Tiêu đề SAU KHI CHÈN NHƯ BEGIN KHAI THÁC @creditrated tinyint, @vendorid int ; CHỌN @creditrated = v. Tín dụng. Đánh giá, @vendorid = p. Người bán. ID TỪ Mua hàng. Mua. Đặt hàng. Tiêu đề p THAM GIA được chèn i ON p. Mua. Đặt hàng. ID = tôi. Mua. Đặt hàng. ID THAM GIA mua hàng. Nhà cung cấp v ON v. Người bán. ID = tôi. Người bán. NHẬN DẠNG ; IF @creditrated = 5 RAISERROR ("Xếp hạng tín dụng của nhà cung cấp này quá thấp để chấp nhận đơn đặt hàng mới.", 16, 1) ; KẾT THÚC

Quản lý trình kích hoạt Vô hiệu hóa/bật trình kích hoạt: – TẮT/BẬT TRIGGER trigger_name TRÊN object_name Tắt/bật tất cả trình kích hoạt bảng: – TẮT/BẬT TRIGGER TẤT CẢ TRÊN object_name Thay đổi trình kích hoạt: – ALTER TRIGGER trigger_name … Xóa trình kích hoạt: – DROP TRIGGER trigger_name

Kích hoạt/hủy kích hoạt trình kích hoạt DISABLE TRIGGER (trigger_name [ , . . n ] | ALL ) ON ( object_name ) ; BẬT TRIGGER (trigger_name [ , . . n ] | ALL ) BẬT ( object_name)

Sử dụng trigger Bảo mật – Từ chối truy cập dựa trên giá trị dữ liệu Kế toán – Ghi nhật ký thay đổi Tính toàn vẹn dữ liệu – Quy tắc toàn vẹn phức tạp – Tính toàn vẹn tham chiếu phức tạp Dữ liệu phái sinh – Tính toán giá trị tự động

Chức năng loại trình kích hoạt SAU KHI kích hoạt THAY VÌ Thực thể kích hoạt Bảng và dạng xem Số lượng trình kích hoạt trên mỗi bảng/nhiều lượt xem cho mỗi sự kiện Một trình kích hoạt cho mỗi sự kiện Không có ràng buộc THAY VỀ CẬP NHẬT và XÓA không thể được xác định cho các bảng tuân theo các ràng buộc toàn vẹn tham chiếu xếp tầng. Liên kết xếp tầng Sau các thao tác sau: Xử lý các ràng buộc. Thực thi Hành động tham chiếu khai báo. Tạo bảng được chèn và xóa. Hành động kích hoạt trigger. Trước hoạt động tiếp theo: Xử lý các ràng buộc. Thay vì thao tác sau: Hành động kích hoạt trình kích hoạt. Sau các thao tác sau: Tạo các bảng được chèn và xóa.

DDL - kích hoạt Trình kích hoạt DDL có thể được sử dụng trong các tác vụ quản trị như kiểm tra và điều tiết các hoạt động cơ sở dữ liệu. Các trình kích hoạt này ảnh hưởng đến tất cả các lệnh cùng loại trong toàn bộ cơ sở dữ liệu hoặc máy chủ.

DDL - Trình kích hoạt Trình kích hoạt DDL, giống như trình kích hoạt thông thường, khiến các thủ tục được lưu trữ kích hoạt để phản hồi lại một sự kiện. Kích hoạt để phản hồi nhiều sự kiện Ngôn ngữ định nghĩa dữ liệu (DDL). Những sự kiện này thường tương ứng với các câu lệnh Transact-SQL bắt đầu bằng các từ khóa CREATE, ALTER hoặc DROP.

Nhiệm vụ của trình kích hoạt DDL Ngăn chặn việc thực hiện một số thay đổi nhất định đối với lược đồ cơ sở dữ liệu. Thực hiện một số hành động trên cơ sở dữ liệu để đáp ứng với những thay đổi trong lược đồ cơ sở dữ liệu. Ghi lại các thay đổi hoặc sự kiện trong lược đồ cơ sở dữ liệu. Trình kích hoạt DDL chỉ kích hoạt sau khi các lệnh DDL tương ứng được thực thi. Trình kích hoạt DDL không thể được sử dụng làm trình kích hoạt INSTEAD OF.

TẠO TRIGGER trigger_name BẬT (CƠ SỞ DỮ LIỆU | TẤT CẢ MÁY CHỦ) ( FOR | AFTER ) ( event_type | event_group ) NHƯ ( sql_statement [ ; ] [ , . . n ] [ ; ] )

Tạo/xóa DDL-tr TẠO TRIGGER ddl_trig_database TRÊN TẤT CẢ CÁC MÁY CHỦ ĐỂ CREATE_DATABASE NHƯ IN "Cơ sở dữ liệu đã được tạo." DROP TRIGGER ddl_trig_database TRÊN TẤT CẢ CÁC MÁY CHỦ;

DDL - kích hoạt TẠO an toàn TRIGGER TRÊN CƠ SỞ DỮ LIỆU CHO DROP_TABLE, ALTER_TABLE NHƯ PRINT "Bạn phải tắt "an toàn" Kích hoạt để loại bỏ hoặc thay đổi bảng!" TRỞ LẠI ;

Bạn có thể tạo nhiều trình kích hoạt DDL cho một câu lệnh Transact-SQL. Trình kích hoạt DDL và lệnh kích hoạt nó được thực thi trong cùng một giao dịch. THAY ĐỔI các sự kiện CƠ SỞ DỮ LIỆU xảy ra bên trong trình kích hoạt DDL không thể khôi phục được. Trình kích hoạt DDL chỉ thực thi sau khi câu lệnh Transact-SQL hoàn thành. Trình kích hoạt DDL không thể được sử dụng làm trình kích hoạt INSTEAD OF. Trình kích hoạt DDL không tạo các bảng được chèn và xóa.

Đăng nhập - kích hoạt Trình kích hoạt đăng nhập thực hiện các thủ tục được lưu trữ để phản hồi sự kiện LOGON. Sự kiện này xảy ra khi phiên người dùng được thiết lập với phiên bản SQL Server. Đăng nhập sẽ kích hoạt sau khi giai đoạn xác thực đăng nhập hoàn tất nhưng trước khi phiên người dùng thực sự được thiết lập.

Đăng nhập - kích hoạt TẠO TRIGGER trigger_name TRÊN TẤT CẢ CÁC MÁY CHỦ ( FOR| AFTER ) ĐĂNG NHƯ ( sql_statement )

Đã có nhiều bài viết trên Internet về trình kích hoạt sql, nhưng tôi sẽ bổ sung thêm một bài nữa với các ví dụ đầy đủ để củng cố tài liệu cho những người “đã biết” và để hiểu rõ hơn tài liệu cho những người mới bắt đầu hiểu về “zen của sql”. Đồng thời, tôi sẽ tạo một cuộc thảo luận về chủ đề này.

Hãy để tôi nói ngay rằng ý kiến ​​​​của tôi chỉ là ý kiến ​​​​của tôi, và đôi khi nó rất có tính phân loại. Vì một số lý do, bạn phải làm việc với các trang web có tải cao và các ứng dụng web phức tạp.

Một kinh nghiệm quý giá học được khi làm việc với chúng là theo dõi các ưu tiên và số liệu thống kê. Nó có nghĩa là gì? Thật đơn giản: nếu bạn có một blog và blog đó có 2-3-4-10012 triệu khách truy cập mỗi ngày và các bài viết chỉ được viết 1-2-3-3435 lần một ngày (một mức độ nhỏ hơn số lượt xem) , thì tốc độ lưu bài viết (và độ phức tạp của bài viết này) so với tốc độ hiển thị của bài viết có thể ít hơn tương ứng. Chúng tôi càng hiển thị nhiều thì việc hiển thị càng quan trọng chứ không phải việc lưu bài viết/trang/bảng. Điều đó không có nghĩa là bạn có thể thư giãn. Lưu một bài viết trong 3-5-10 giây trên blog là nằm trong giới hạn phù hợp, nhưng việc tạo một trang trong hơn 2 giây (+ trong khi tải tập lệnh và kiểu có hình ảnh) đang ở mức gần như “trang web chậm quá”. , Tôi sẽ đọc thứ khác”, và thậm chí tệ hơn, “Tôi sẽ đi mua nó ở nơi khác.”

Nếu chúng ta lấy một trang web trung bình có phiếu bầu/nghiệp, nhận xét, bộ đếm số lần hiển thị trang, v.v., thì nhiều nhà phát triển ngay lập tức nghĩ đến các cấu trúc như SELECT count(*) FROM comment WHERE comment.page=page_id. Chà, hãy nghĩ đến việc tính toán số lượng xếp hạng và số lượng bình luận cho mỗi bài viết. Ồ, chúng tôi có 10 bài viết từ mỗi phần trên trang chính. Với lưu lượng truy cập 10 người mỗi giây, trên một VPS trung bình, bạn có thể thực hiện 60-100 truy vấn SQL trên mỗi trang (xin chào, Bitrix).

Nhưng chết tiệt với lời bài hát (có lẽ tôi đã chán nó rồi). Dữ liệu trần:

bảng blog

TẠO BẢNG NẾU KHÔNG Tồn tại `blog` (`id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(128) NOT NULL, `text` text NOT NULL, `creation` datetime NOT NULL, `modification` datetime NOT NULL , `img` varchar(128) NOT NULL MẶC ĐỊNH "default.png", `status` tinyint(4) NOT NULL DEFAULT "2", `user_id` int(11) NOT NULL, `rate` int(11) NOT NULL , `relax_type` tinyint(4) NOT NULL, `timers` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `contest` tinyint(1) NOT NULL DEFAULT "0", `views` int(11) NOT NULL DEFAULT "0", `comment ` int(11) NOT NULL, `url` varchar(128) NOT NULL, PRIMARY KEY (`id`), KHÓA ĐỘC ĐÁO `url` (`url`), KEY `country_id` (`country_id`), KEY `user_id ` (`user_id`), KEY `status` (`status`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1456435 ;

Bảng bình luận

TẠO BẢNG NẾU KHÔNG Tồn tại `comments` (`owner_name` varchar(50) NOT NULL, `owner_id` int(12) NOT NULL, `id` int(12) NOT NULL AUTO_INCREMENT, `parent_id` int(12) DEFAULT NULL, `user_id` int(12) DEFAULT NULL, `text` text, `creation` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `status` int(1) NOT NULL DEFAULT "0", PRIMARY KEY (`id`), KEY `owner_name` ( `owner_name`,`owner_id`), KEY `parent_id` (`parent_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=243254252 ;

Như bạn thấy, trong bảng blog, mỗi bài viết đều có một bộ đếm bình luận (trường bình luận).
Thực hành đơn giản:
1. Đã thêm bình luận - tăng bộ đếm cho blog
2. Đã xóa/ẩn bình luận - giảm bộ đếm.
Thực hiện việc này bằng mã rất thuận tiện và quen thuộc, nhưng có một công cụ thuận tiện hơn - trình kích hoạt.

Và vì vậy, chúng ta có 2 sự kiện (thực tế là 3): tạo một bình luận và xóa bình luận đó (sự kiện thứ ba là thay đổi trạng thái của nó (“xóa”, cấm, v.v.).
Hãy chỉ xem xét việc tạo và xóa và hãy để việc thay đổi trạng thái là bài tập về nhà của bạn.

Có một tính năng trong ví dụ: bình luận có thể dành cho một số loại bài viết.

Tạo bình luận:

TẠO KÍCH HOẠT `add_count_comment` SAU KHI CHÈN VÀO `bình luận` CHO MỖI HÀNG BẮT ĐẦU // trong tài khoản cá nhân của người dùng, chúng tôi sẽ đếm xem anh ta đã viết bao nhiêu nhận xét CẬP NHẬT user SET user.countcomment= user.countcomment+1 WHERE user.id = NEW.user_id ; // xác định xem bình luận đề cập đến điều gì và ngay lập tức tăng bộ đếm trong các bảng này TRƯỜNG HỢP MỚI.`owner_name` KHI "Blog" SAU ĐÓ CẬP NHẬT `blog` SET `blog`.`comment` = `blog`.`comment`+1 WHERE `blog `.id = MỚI.`owner_id` ; KHI "Bài viết" THÌ CẬP NHẬT `article` SET `article`.`comment` = `article`.`comment`+1 WHERE `article`.`id` = NEW.`owner_id` ; KHI "PopulatePlace" SAU ĐÓ CẬP NHẬT `populate_place` THIẾT LẬP `populate_place`.`comment` = `populate_place`.`comment`+1 WHERE `populate_place`.`id` = NEW.`owner_id` ; KẾT THÚC TRƯỜNG HỢP; // ở đây chúng tôi giúp bản thân làm việc với các nguồn cấp tin tức dễ dàng hơn // chúng tôi viết url của bài viết ngay lập tức, để SAU ĐÓ chúng tôi không phải đưa ra những lựa chọn không cần thiết TRƯỜNG HỢP MỚI.`owner_name` KHI "Blog" THÌ THIẾT LẬP userurl = (CHỌN url TỪ `blog` Ở ĐÂU `blog`. id= NEW.`owner_id`); KHI "Bài viết" THÌ THIẾT LẬP userurl = (CHỌN url TỪ `bài viết` WHERE bài viết.id=NEW.`owner_id`); KHI "PopulatePlace" THÌ THIẾT LẬP userurl = ``; KẾT THÚC TRƯỜNG HỢP; // viết ngay tiêu đề bài viết để không phải lựa chọn SAU ĐÓ LÀ TRƯỜNG HỢP MỚI.`owner_name` KHI "Blog" THÌ THIẾT LẬP usertitle = (chọn tiêu đề từ `blog` trong đó blog.id=NEW.`owner_id`) ; KHI "Bài viết" THÌ THIẾT LẬP usertitle = (chọn tiêu đề từ `bài viết` trong đó bài viết.id=NEW.`owner_id`); KHI "PopulatePlace" THÌ THIẾT LẬP usertitle = ` `; KẾT THÚC TRƯỜNG HỢP; XÁC NHẬN VÀO user_has_events GIÁ TRỊ (NEW.user_id,NEW.id,"Comments",NOW(),userurl , usertitle); KẾT THÚC

Điều tương tự cũng xảy ra với việc xóa một bình luận:

TẠO TRIGGER `del_count_comment` SAU KHI XÓA TRÊN `bình luận` CHO MỖI HÀNG BẮT ĐẦU CẬP NHẬT user SET user.countcomment= user.countcomment -1 WHERE user.id = OLD.user_id; TRƯỜNG HỢP OLD.`owner_name` KHI "Blog" THÌ CẬP NHẬT `blog` SET `blog`.`comment` = `blog`.`comment`-1 WHERE `blog`.`id` = OLD.`owner_id` ; KHI "Bài viết" THÌ CẬP NHẬT `article` SET `article`.`comment` = `article`.`comment`-1 WHERE `article`.`id` = OLD.`owner_id` ; KHI "PopulatePlace" SAU ĐÓ CẬP NHẬT `populate_place` THIẾT LẬP `populate_place`.`comment` = `populate_place`.`comment`-1 WHERE `populate_place`.`id` = OLD.`owner_id` ; KẾT THÚC TRƯỜNG HỢP; KẾT THÚC

Và như vậy những gì chúng tôi nhận được:
1. Khi chèn bình luận, chúng tôi tự động tính toán lượng bình luận cho một đối tượng bình luận cụ thể (bài viết, trang, ghi chú) bằng máy chủ sql.
2. Chúng tôi đã tạo một nguồn cấp tin tức (xin chào tất cả các mạng xã hội, v.v.)
3. Khi bạn xóa bình luận, chúng tôi sẽ khấu trừ toàn bộ dữ liệu.
4. Chúng tôi không sử dụng bất kỳ công cụ khung nào.
5. Việc truy xuất tất cả dữ liệu cần thiết diễn ra nhanh chóng (chỉ 1 yêu cầu khi hiển thị một trang, ngoại trừ các dữ liệu “trái” khác trên đó.)

Chúng tôi cũng có nhân sư, cơ quan này định kỳ đưa ra các lựa chọn về các bài viết đã thay đổi vào phút chót. Với mục đích này, blog có một trường sửa đổi.

Đã thêm trình kích hoạt:

TẠO TRIGGER `ins_blog` TRƯỚC KHI CHÈN VÀO `blog` // chèn thời gian trước khi lưu thông tin bằng cách “thay thế” dữ liệu. CHO MỖI HÀNG BẮT ĐẦU THIẾT LẬP MỚI.modification = NOW(); KẾT THÚC

Bây giờ, thực hiện lựa chọn vào phút cuối, chúng ta sẽ nhận được tất cả các tài liệu đã được thêm vào phút cuối.

TẠO TRIGGER `ins_blog` TRƯỚC KHI CẬP NHẬT TRÊN `blog` // chèn thời gian trước khi lưu thông tin bằng cách “thay thế” dữ liệu. CHO MỖI HÀNG BẮT ĐẦU THIẾT LẬP MỚI.modification = NOW(); KẾT THÚC

Nếu dữ liệu thay đổi, chúng tôi cũng sẽ cập nhật chỉ mục tìm kiếm.

Thông thường, trong một dự án trung bình, mọi thứ có thể chuyển sang phía máy chủ sql đều được chuyển. Bản thân máy chủ sql thực hiện các hoạt động như vậy nhanh hơn và sử dụng ít tài nguyên hơn mức có thể thực hiện được thông qua ngôn ngữ lập trình được sử dụng.

CẬP NHẬT: Holivar dành cho tính khả thi của việc làm phức tạp cấu trúc cơ sở dữ liệu được khai báo mở.

Cò súng cơ sở dữ liệu là một khối PL/SQL được thiết kế đặc biệt có tên được lưu trữ trong cơ sở dữ liệu. Mỗi trình kích hoạt được liên kết với một bảng cụ thể và được ORACLE tự động khởi chạy khi một trong các câu lệnh DML (CHÈN, XÓA, CẬP NHẬT) hoặc kết hợp chúng được thực thi trên bảng này.

Mục đích của trigger. Trigger có thể được sử dụng:

1) để triển khai các ràng buộc toàn vẹn dữ liệu phức tạp không thể triển khai theo cách tiêu chuẩn khi tạo bảng;

2) ngăn chặn các giao dịch không chính xác;

3) thực hiện các thủ tục xác minh toàn diện quyền truy cập và bảo mật dữ liệu;

4) tạo một số biểu thức dựa trên các giá trị có sẵn trong các cột của bảng;

5) thực hiện các quy tắc kinh doanh phức tạp để xử lý dữ liệu (khả năng theo dõi “tiếng vang”, tức là khả năng cập nhật dữ liệu của các bảng liên quan khi một bảng thay đổi).

Tạo và kích hoạt trình kích hoạt.Để tạo và tự động kích hoạt trình kích hoạt, cú pháp chung sau đây được sử dụng:

TẠO TRIGGER trigger_name

(TRƯỚC | SAU)

(CHÈN | XÓA | CẬP NHẬT)

TRÊN tên_bảng

< PL/SQL_блок >

Nếu có từ khóa OR REPLACE thì trình kích hoạt sẽ được tạo lại nếu nó đã tồn tại.

TRƯỚC KHI thiết kế | SAU cho biết thời điểm kích hoạt được kích hoạt. Tùy chọn TRƯỚC có nghĩa là trình kích hoạt sẽ kích hoạt trước khi thực thi câu lệnh DML kích hoạt; tùy chọn SAU có nghĩa là trình kích hoạt sẽ kích hoạt sau khi thực thi câu lệnh DML kích hoạt.

CHÈN | XÓA | CẬP NHẬT chỉ định loại câu lệnh DML kích hoạt trình kích hoạt. Được phép sử dụng phép toán logic OR để chỉ định một tập hợp các toán tử kích hoạt, ví dụ: CHÈN HOẶC XÓA. Khi sử dụng tùy chọn CẬP NHẬT, nếu danh sách các cột được chỉ định, trình kích hoạt sẽ kích hoạt khi một trong các cột được chỉ định bị sửa đổi; nếu không có danh sách các cột thì trình kích hoạt sẽ được kích hoạt khi bất kỳ cột nào trong bảng được liên kết với trình kích hoạt thay đổi.

Cấu trúc FOR EACH ROW cho biết bản chất của hành động kích hoạt: chuỗi hoặc toán tử. Nếu có mệnh đề FOR ​​EACH ROW thì trình kích hoạt là một chuỗi; trong trường hợp không có nó, trình kích hoạt là toán tử. Trình kích hoạt câu lệnh sẽ kích hoạt một lần trước hoặc sau khi câu lệnh DML kích hoạt trình kích hoạt được thực thi, bất kể có bao nhiêu hàng trong bảng được liên kết với trình kích hoạt được sửa đổi. Trình kích hoạt hàng được kích hoạt một lần cho mỗi hàng được sửa đổi bởi câu lệnh DML kích hoạt trình kích hoạt.

Sử dụng từ khóa WHEN, bạn có thể chỉ định một hạn chế bổ sung trên các hàng của bảng được liên kết với trình kích hoạt, khi được sửa đổi, trình kích hoạt có thể được kích hoạt.

Cấu trúc PL/SQL_block đại diện cho khối PL/SQL mà ORACLE chạy khi kích hoạt trình kích hoạt.

Phân loại trigger. Về cơ bản có mười hai loại kích hoạt. Loại trình kích hoạt được xác định bằng sự kết hợp của ba tham số sau:

1) bản chất tác động của trình kích hoạt lên các hàng của bảng được liên kết với nó (chuỗi hoặc toán tử);

2) thời điểm trình kích hoạt được khởi chạy: trước (TRƯỚC) hoặc sau (SAU) việc thực thi câu lệnh DML kích hoạt trình kích hoạt;

3) loại toán tử DML kích hoạt trình kích hoạt (CHÈN, XÓA, CẬP NHẬT);

Thứ tự kích hoạt trigger. Nếu một bảng có một số loại trình kích hoạt, chúng sẽ được kích hoạt theo sơ đồ sau:

1) trình kích hoạt toán tử TRƯỚC KHI được thực thi (nếu có một vài trong số chúng, thì không thể nói gì về thứ tự thực hiện của chúng);

2) trình kích hoạt chuỗi TRƯỚC được thực thi;

3) toán tử DML kích hoạt trình kích hoạt được thực thi, sau đó kiểm tra tất cả các ràng buộc về tính toàn vẹn dữ liệu;

4) trình kích hoạt chuỗi SAU được thực thi, sau đó là kiểm tra tất cả các ràng buộc về tính toàn vẹn dữ liệu;

5) lệnh kích hoạt toán tử SAU được thực thi.

Vị ngữ kích hoạt. Nếu một trình kích hoạt chỉ định một tập hợp các toán tử DML kích hoạt trình kích hoạt (ví dụ: CHÈN HOẶC XÓA), thì để nhận biết toán tử DML cụ thể nào được thực thi trên bảng được liên kết với trình kích hoạt, các vị từ của trình kích hoạt sẽ được sử dụng: CHÈN, XÓA, CẬP NHẬT. Chúng là các hàm logic trả về TRUE nếu loại toán tử kích hoạt khớp với loại vị từ và FALSE nếu không. Để chỉ định các hành động tương tự khi các câu lệnh DML khác nhau được thực thi trong một câu lệnh có điều kiện, các vị từ kích hoạt được kết hợp bằng các phép toán logic.

Bản ghi giả.Đối với trình kích hoạt chuỗi, có các cấu trúc đặc biệt cho phép, khi thực hiện các thao tác DML trên một hàng của bảng, truy cập cả các giá trị cũ có trong đó trước khi sửa đổi và các giá trị mới sẽ xuất hiện trong hàng sau khi sửa đổi. Những cấu trúc này được gọi là bản ghi giả và được biểu thị là cũ và mới. Cấu trúc của các bản ghi giả này giống hệt với cấu trúc của hàng trong bảng đang được sửa đổi, nhưng bạn chỉ có thể thao tác trên các trường riêng lẻ của bản ghi giả. Các trường của bản ghi giả được truy cập theo sơ đồ sau: trước ký hiệu cũ hoặc mới đặt ký hiệu “:”, sau đó tên của trường được biểu thị bằng dấu chấm. Các giá trị mà trường bản ghi giả đảm nhận khi kích hoạt câu lệnh DML được thực thi được xác định như sau.

Câu lệnh INSERT - pseudo-record:new tương đương với hàng được chèn và pseudo-record:old là NULL trong tất cả các trường.

Câu lệnh DELETE - pseudo-record:old tương đương với hàng bị xóa và pseudo-record:new là NULL trong tất cả các trường.

Câu lệnh UPDATE - bản ghi giả:mới tương đương với hàng do sửa đổi và bản ghi giả:cũ trong tất cả các trường là giá trị hàng ban đầu.

Bật và tắt kích hoạt. Trình kích hoạt được lưu trữ trong cơ sở dữ liệu có thể bị vô hiệu hóa tạm thời mà không cần xóa nó khỏi cơ sở dữ liệu. Để thực hiện việc này, hãy sử dụng lệnh sau:

THAY ĐỔI TRIGGER trigger_name TẮT;

Bạn có thể kích hoạt trình kích hoạt sau một khoảng thời gian nhất định bằng lệnh

THAY ĐỔI TRIGGER trigger_name BẬT;

Bạn có thể vô hiệu hóa hoặc cho phép kích hoạt tất cả các trình kích hoạt được liên kết với một bảng nhất định bằng lệnh

THAY ĐỔI TABLE table_name (DISABLE | ENABLE) TẤT CẢ CÁC KÍCH HOẠT;

trong đó tùy chọn DISABLE được sử dụng để tắt và tùy chọn ENABLE được sử dụng để kích hoạt tất cả các trình kích hoạt của một bảng nhất định.

Loại bỏ trình kích hoạt khỏi cơ sở dữ liệu. Việc hủy trình kích hoạt, tức là xóa trình kích hoạt khỏi cơ sở dữ liệu, được thực hiện bằng lệnh sau:

THẢ TRIGGER trigger_name;

Thu thập thông tin về trigger. Trình kích hoạt được lưu trữ trong cơ sở dữ liệu, do đó, thông tin về chúng có thể được truy xuất từ ​​chế độ xem từ điển dữ liệu USER_TRIGGERS, chẳng hạn bằng lệnh sau:

CHỌN * TỪ NGƯỜI DÙNG_TRIGGERS;

Ví dụ.

1. Tạo trình kích hoạt để trước khi chèn hàng tiếp theo vào bảng KNIGA_POSTAVKA, hãy kiểm tra sự hiện diện của mã sách được chỉ định trong bảng KNIGA. Nếu mã sách được chỉ định không có trong bảng KNIGA, thì sẽ tạo một ngoại lệ với thông báo tương ứng.

Các hàng mới được thêm vào bảng KNIGA_POSTAVKA bằng câu lệnh INSERT. Vì trình kích hoạt phải kích hoạt trước khi thực hiện mỗi câu lệnh INSERT nên nó phải là một chuỗi TRƯỚC trình kích hoạt. Để duy trì tính toàn vẹn của dữ liệu, cần kiểm tra xem mã sách đã nhập có nằm trong bảng KNIGA hay không. Để thực hiện việc này, bằng cách sử dụng câu lệnh SELECT một dòng, thông tin được lấy từ bảng KNIGA, trong đó trường BOOK_CODE của bản ghi giả được sử dụng trong điều kiện lựa chọn: mới. Nếu số hàng có mã sách nhất định trong bảng KNIGA bằng 0, một ngoại lệ sẽ được tạo và thông báo tương ứng sẽ được đưa ra.

Trình kích hoạt TR1 được tạo bằng cách nhập câu lệnh sau:

TẠO HOẶC THAY THẾ TRIGGER TR1

TRƯỚC KHI CHÈN TRÊN KNIGA_POSTAVKA

CHỌN ĐẾM(*) VÀO KOL TỪ KNIGA

WHERE BOOK_CODE = :NEW.BOOK_CODE;

NẾU KOL = 0 THÌ RAISE_APPLICATION_ERROR

(–20212,"Bảng KNIGA không chứa thông tin về cuốn sách này");

Hành động của trình kích hoạt TR1 có thể được kiểm tra bằng cách thực hiện câu lệnh sau, câu lệnh này sẽ chèn một hàng vào bảng KNIGA_POSTAVKA và do đó khiến trình kích hoạt TR2 được kích hoạt:

XÁC NHẬN VÀO GIÁ TRỊ KNIGA_POSTAVKA(21,15,’Ivanov’,15,

Vì mã sách 15 không có trong bảng KNIGA nên một ngoại lệ sẽ được đưa ra và một thông báo tương ứng sẽ được đưa ra.

2. Tạo trình kích hoạt cấm nhập vào các hàng của bảng KNIGA có giá trị trường PRICE lớn hơn 5.000 rúp, cũng như tăng giá sách, thông tin về những sách được lưu trữ trong bảng KNIGA, lên hơn 20%. Nếu yêu cầu này bị vi phạm, một ngoại lệ phải được tạo bằng một thông báo thích hợp.

Vì các hàng mới được thêm vào bảng KNIGA do thực hiện câu lệnh INSERT và giá trị của trường PRICE trong bảng KNIGA, chứa giá của cuốn sách, có thể được thay đổi do thực thi câu lệnh UPDATE, nên trigger chỉ định một tập hợp các câu lệnh DML kích hoạt. Vì trình kích hoạt phải kích hoạt trước khi thực thi từng câu lệnh DML được chỉ định nên nó là một chuỗi TRƯỚC trình kích hoạt. Do các hành động được thực hiện bởi trình kích hoạt là khác nhau đối với mỗi câu lệnh DML kích hoạt sửa đổi bảng KNIGA, nên các vị từ kích hoạt tương ứng INSERTING và UPDAITING được sử dụng để nhận dạng loại câu lệnh DML. Do khi chèn hàng mới phải kiểm tra giá trị mới của trường PRICE và khi sửa giá trị của trường PRICE thì phải so sánh giá trị mới với giá trị cũ nên phải sử dụng bản ghi giả : mới và cũ.

Việc tạo trình kích hoạt TR2 được thực hiện bằng cách nhập câu lệnh sau:

TẠO HOẶC THAY THẾ TRIGGER TR2

TRƯỚC KHI CHÈN HOẶC CẬP NHẬT GIÁ TRÊN KNIGA

NẾU CHÈN THÌ

NẾU: MỚI.PRICE > 5000 THÌ

RAISE_APPLICATION_ERROR

(–20102, "Không thể tạo các bản ghi có giá sách > 5000 trong bảng KNIGA");

NẾU CẬP NHẬT THÌ

NẾU:NEW.PRICE > :OLD.PRICE*1,2 THÌ

RAISE_APPLICATION_ERROR

(–20103, “Trong bảng KNIGA, bạn không thể thay đổi giá sách quá 20%”);

Hoạt động của trình kích hoạt TR2 có thể được kiểm tra bằng cách thực hiện các câu lệnh sau, bằng cách chèn các hàng vào bảng KNIGA và cập nhật các hàng trong bảng KNIGA, từ đó khiến nó được kích hoạt.

Toán tử chèn hàng vào bảng KNIGA, khiến trigger TR2 được kích hoạt:

CHÈN VÀO GIÁ TRỊ KNIGA(21, "Dune", "Herbert", 5268, "Ast",

"Tuyệt vời");

Toán tử cập nhật hàng trong bảng KNIGA, khiến trình kích hoạt TR2 được kích hoạt:

CẬP NHẬT GIÁ BỘ KNIGA=6000;

Vì những tuyên bố này vi phạm các yêu cầu về giá trị và việc sửa đổi giá sách nên một ngoại lệ sẽ được tạo ra trong mọi trường hợp và một thông báo tương ứng sẽ được đưa ra.

3. Tạo trình kích hoạt vào bảng STAT đã tạo có chứa các cột:

tên nhà xuất bản – IZD,

số lượng sách thuộc thể loại “Tiểu thuyết” – KOL_ROM,

số lượng sách thuộc thể loại Khoa học viễn tưởng – KOL_FAN,

với mỗi lần sửa đổi bảng, KNIGA tạo và nhập vào các cột tương ứng của bảng STAT tổng số sách cho mỗi nhà xuất bản trong bối cảnh các chủ đề được chỉ định: “Tiểu thuyết” và “Tiểu thuyết”.

Việc sửa đổi bảng KNIGA được thực hiện bằng cách thực hiện các câu lệnh DML sau: toán tử INSERT, DELETE hoặc UPDATE, sửa đổi giá trị của cột GENRE trong bảng KNIGA. Vì các hành động tạo thông tin trong bảng STAT được thực hiện sau khi thực hiện từng toán tử sửa đổi bảng KNIGA, nên đây là trình kích hoạt toán tử SAU theo loại. Vì các hành động được thực hiện bởi trình kích hoạt là giống nhau đối với tất cả các loại toán tử kích hoạt nó nên các vị từ của trình kích hoạt không được sử dụng. Trước khi tạo trigger, bảng STAT phải được tạo.

Việc tạo bảng STAT có thể được thực hiện bằng cách nhập tập hợp câu lệnh sau:

THỐNG KÊ BẢNG THẢ;

TẠO BẢNG THỐNG KÊ

(IZD VARCHAR2(15),

SỐ KOL_ROM(7),

KOL_SỐ NGƯỜI FAN(7)

Việc tạo trình kích hoạt TR3 được thực hiện bằng cách nhập câu lệnh sau:

TẠO HOẶC THAY THẾ TRIGGER TR3

SAU KHI CHÈN HOẶC XÓA HOẶC CẬP NHẬT THỂ LOẠI

CURSOR V1 LÀ NHÀ XUẤT BẢN CHỌN

QUẬN(TÊN) KOL1

TỪ KNIGA Ở ĐÂU THỂ LOẠI = "Tiểu thuyết"

NHÓM THEO NHÀ XUẤT BẢN;

CURSOR V2 LÀ NHÀ XUẤT BẢN CHỌN,

QUẬN(TÊN) KOL2

TỪ KNIGA Ở ĐÂU THỂ LOẠI = "Tiểu thuyết"

NHÓM THEO NHÀ XUẤT BẢN;

XÓA TỪ STAT;

CHO VÒNG Z1 TRONG V1

CHÈN VÀO GIÁ TRỊ STAT(Z1.PUBLISHER,

CHO VÒI Z1 TRONG V2

CẬP NHẬT THỐNG KÊ KOL_FAN = Z1.KOL2

Ở ĐÂU IZD = Z1.Nhà xuất bản;

NẾU SQL% KHÔNG TÌM THẤY THÌ

CHÈN VÀO GIÁ TRỊ STAT(Z1.PUBLISHER, 0,

Hoạt động của trình kích hoạt có thể được kiểm tra bằng cách thực hiện các câu lệnh sau, bằng cách chèn các hàng vào bảng KNIGA, xóa các hàng và cập nhật các hàng trong bảng KNIGA, từ đó kích hoạt TR3.

Toán tử chèn hàng vào bảng KNIGA, khiến kích hoạt TR3 được kích hoạt:

CHÈN VÀO CÁC GIÁ TRỊ KNIGA(46, "Heretics of Dune", "Herbert",368,

"Thật tuyệt vời", "Tuyệt vời");

CHÈN VÀO GIÁ TRỊ KNIGA(42, "Ingvar và Alder",

"Nikitin", 168, "Ast", "La Mã");

Toán tử xóa các hàng khỏi bảng KNIGA, khiến trình kích hoạt TR3 được kích hoạt:

XÓA KNIGA Ở ĐÂU TÊN = "Cossacks";

Các toán tử sửa đổi hàng trong bảng KNIGA khiến trình kích hoạt TR3 được kích hoạt:

CẬP NHẬT KNIGA BỘ THỂ LOẠI="Fiction" WHERE NAME =

"Ingvar và Alder";

Bạn có thể xem thông tin trong bảng STAT bằng câu lệnh sau.

  1. Tìm hiểu các loại trình kích hoạt có thể được tạo trên máy chủ MS SQL Server 2000.
  2. Nghiên cứu các toán tử để mô tả các loại trình kích hoạt khác nhau và các hạn chế áp đặt cho các toán tử hợp lệ trong phần thân của trình kích hoạt.
  3. Tìm hiểu cách tạo và gỡ lỗi trình kích hoạt trên MS SQL Server 2000.
  4. Phát triển năm trình kích hoạt cho cơ sở dữ liệu đào tạo “Thư viện”, do giáo viên của bạn đề xuất từ ​​các nhiệm vụ được mô tả trong tác phẩm.
  5. Lập báo cáo về công việc đã thực hiện dưới dạng điện tử.

1. Tạo trình kích hoạt

Gây nênđây là những phương pháp mà nhà phát triển ứng dụng cho MS SQL Server có thể đảm bảo tính toàn vẹn của cơ sở dữ liệu. Đây là một loại thủ tục lưu trữ được gọi khi cố gắng thay đổi dữ liệu trong bảng mà trình kích hoạt được xác định. SQL Server thực hiện quy trình này trong các thao tác chèn, cập nhật và xóa (CHÈN, CẬP NHẬT, XÓA) trên một bảng nhất định. Vì trình kích hoạt được áp dụng sau khi thao tác hoàn tất nên nó đại diện cho từ cuối cùng được sửa đổi. Nếu trình kích hoạt gây ra lỗi trong truy vấn, SQL Server sẽ từ chối cập nhật thông tin và trả về thông báo lỗi cho ứng dụng thực hiện hành động đó. Nếu một trình kích hoạt được xác định cho một bảng thì không thể bỏ qua nó khi thực hiện thao tác tương ứng.

Mặc dù trình kích hoạt là một loại thủ tục được lưu trữ, nhưng nó không thể được gọi trực tiếp: nó chỉ phản hồi với các sự kiện mà nó được xác định.

Một loại trình kích hoạt mới đã xuất hiện trong MS SQL SERVER 2000 - INSTEAD OF -trigger. Sự khác biệt cơ bản của nó so với các trình kích hoạt (SAU) thông thường là nó được thực thi không phải sau thao tác chèn, sửa đổi hoặc xóa mà thay vào đó.

Công dụng phổ biến nhất của trigger là duy trì tính toàn vẹn trong cơ sở dữ liệu.

Trình kích hoạt có tác động nhỏ đến hiệu suất của máy chủ và thường được sử dụng để nâng cao các mệnh đề thực hiện các thao tác nhiều bước trên bảng và hàng.

Để tạo trình kích hoạt, bạn phải là chủ sở hữu của bảng nơi trình kích hoạt được tạo hoặc là thành viên của vai trò db_owner hoặc db_ddladmin hoặc là quản trị viên của máy chủ SQL, nghĩa là là thành viên của vai trò máy chủ cố định quản trị viên hệ thống. Khi bạn thêm trình kích hoạt vào bảng, nó sẽ thay đổi kiểu truy cập, mối quan hệ của các đối tượng khác với bảng, v.v.

Việc tạo trigger cũng tương tự như khai báo một thủ tục lưu sẵn và có cú pháp như sau:

TẠO TRIGGER trigger_name
Trên bàn
{
(CHO | SAU | THAY THẾ) ( [,] [,] )

BẰNG
(NẾU CẬP NHẬT(cột_i)
[(VÀ | HOẶC) CẬP NHẬT (cột_j)]
[... N]
| NẾU (COLUMNS_UPDATED() (bit_operator) bit_mask)
(comparison_operator) cột_bitmask [… n]
}
Câu lệnh SQL [... n]
}
}

  • trigger_name phải tuân theo các quy ước đặt tên đối tượng SQL Server tiêu chuẩn và là duy nhất trong cơ sở dữ liệu;
  • tên bảng của bảng mà trình kích hoạt được tạo;
  • VỚI MÃ HÓA Tùy chọn này cung cấp cho nhà phát triển khả năng ngăn người dùng đọc văn bản kích hoạt sau khi nó được tải lên máy chủ. Một lần nữa, hãy lưu ý rằng để làm cho văn bản kích hoạt thực sự không thể phục hồi được, bạn nên xóa các hàng tương ứng khỏi bảng syscomments sau khi mã hóa;
  • FOR DELETE , INSERT , UPDATE các từ khóa xác định thao tác sửa đổi bảng, khi thực hiện thao tác đó, trình kích hoạt sẽ được kích hoạt;
  • VỚI PHỤ LỤC, tùy chọn này chỉ được yêu cầu nếu mức tương thích đã đặt không vượt quá 65 và được sử dụng để tạo các trình kích hoạt bổ sung;
  • NOT FOR REPLICATION chỉ ra rằng trigger không được kích hoạt khi một bảng được sửa đổi trong quá trình sao chép;
  • Từ khóa AS chỉ định phần đầu của định nghĩa trình kích hoạt;
  • SQL_statements Trong T-SQL, một trigger có thể chứa bất kỳ số lượng câu lệnh SQL nào miễn là chúng được đặt trong dấu ngoặc toán tử BEGIN ... END ;
  • IF UPDATE (cột) cho các thao tác thêm và cập nhật dữ liệu, bạn có thể xác định các điều kiện bổ sung cho một cột trong bảng cụ thể; khi chỉ định nhiều cột, chúng được phân tách bằng toán tử logic;
  • IF (COLUMNS_UPDATED()) Ở trên chúng tôi đã trình bày cách bạn có thể sử dụng cấu trúc IF UPDATE (cột) để xác định cột nào bị ảnh hưởng bởi các thay đổi. Nếu bạn cần kiểm tra xem một cột cụ thể có đang thay đổi hay không, cấu trúc này rất thuận tiện. Tuy nhiên, khi xây dựng một điều kiện phức tạp bao gồm nhiều cột, việc xây dựng này trở nên quá cồng kềnh. Cấu trúc IF (COLUMNS_UPDATED()) dành cho những trường hợp như vậy. Kết quả của hàm COLUMNS_UPDATED() là một tập hợp các bit, mỗi bit tương ứng với một cột trong bảng; Bit có trọng số thấp nhất tương ứng với cột đầu tiên, bit có trọng số cao nhất tương ứng với cột cuối cùng. Nếu thao tác khiến trình kích hoạt kích hoạt cố gắng thay đổi một cột nhất định thì bit tương ứng sẽ được đặt thành 1;
  • toán tử bit Toán tử bitwise xác định hoạt động phân bổ các bit mong muốn thu được bằng cách sử dụng COLUMNS_UPDATED() . Thông thường, toán tử & được sử dụng;
  • bit_mask kết hợp với toán tử bitwise, bitmask cho phép bạn làm nổi bật các bit mà nhà phát triển quan tâm, nghĩa là xác định xem các cột quan tâm có bị thay đổi trong thao tác khiến trình kích hoạt kích hoạt hay không;
  • toán tử so sánhcột_bitmask Hàm COLUMNS_UPDATED() cung cấp tập hợp các bit tương ứng với các cột đang được cập nhật. Sử dụng mặt nạ bit và toán tử bitwise, một phép biến đổi được thực hiện trên tập hợp bit này và thu được kết quả trung gian. Toán tử so sánh so sánh kết quả trung gian này với mặt nạ bit của cột. Nếu kết quả so sánh là đúng thì tập hợp các câu lệnh SQL tạo nên phần thân của trình kích hoạt sẽ được thực thi, nếu không thì sẽ không được thực thi.

Cho bảng có cấu trúc như sau:

TẠO bảng mytable (a int, b int, c int, d int, e int)

Năm cột tương ứng với năm bit, trong đó cột có trọng số thấp nhất tương ứng với cột a, cột có trọng số cao nhất tương ứng với cột e. Hãy để thao tác kích hoạt trình kích hoạt sửa đổi các cột a, b và e. Khi đó hàm columns_updated sẽ cho giá trị 10011. Chúng ta không quan tâm đến việc thay đổi cột b và d mà quan tâm đến việc thay đổi tất cả các cột khác (a, c và e), tức là mặt nạ sẽ là 10101. Hãy nhớ lại rằng Tại thời điểm viết trình kích hoạt, chúng ta không biết cột nào sẽ bị ảnh hưởng bởi thao tác sửa đổi hoặc chèn này hay cột kia, tức là hàm columns_updated sẽ cho kết quả gì. Bằng cách chỉ định toán tử so sánh theo bit trong thời gian chạy, chúng ta nhận được 10011 & 10101, kết quả là 10001, theo ký hiệu thập phân là 17. So sánh giá trị này bằng toán tử so sánh và mặt nạ bit cột sẽ cho chúng ta biết liệu thao tác thay đổi/chèn có thỏa mãn yêu cầu hay không điều kiện. Vì vậy, ví dụ: nếu logic nghiệp vụ yêu cầu trình kích hoạt kích hoạt khi tất cả các cột mà chúng ta quan tâm thay đổi (a, c, e), thì tất nhiên các tham số bitmask và cột_bitmask phải có cùng giá trị và toán tử so sánh phải là dấu bằng. Vì vậy, trong ví dụ của chúng tôi, toàn bộ cấu trúc sẽ trông như sau:

IF(cột_updated & 17) = 17

Nếu yêu cầu ít nhất một trong các cột mà chúng ta quan tâm thay đổi thì cách xây dựng sẽ như sau:

NẾU (cột_updated & 17) > 0

Sử dụng các thao tác bit, bạn có thể đạt được sự linh hoạt cao trong việc soạn thảo các cấu trúc như vậy.

Bạn cũng có thể tạo trình kích hoạt bằng SQL Server Enterprise Manager.

  1. Khởi động Trình quản lý doanh nghiệp SQL Server.
  2. Nhấp chuột phải vào bảng mà bạn muốn tạo trình kích hoạt và chọn Tác vụ > Quản lý trình kích hoạt từ menu ngữ cảnh. Kết quả của những hành động này là một hộp thoại sẽ xuất hiện trong đó bạn có thể nhập văn bản kích hoạt và gán tên cho nó.
  3. Sau khi nhập xong, bạn có thể kiểm tra cú pháp và nhấp vào OK để lưu trình kích hoạt vào cơ sở dữ liệu.

Hạn chế khi tạo trigger

  • Câu lệnh CREATE TRIGGER chỉ có thể được sử dụng trên một bảng.
  • Trình kích hoạt chỉ có thể được tạo trong cơ sở dữ liệu hiện tại nhưng nó có thể tham chiếu các đối tượng bên ngoài.
  • Trong một câu lệnh tạo trình kích hoạt, bạn có thể chỉ định một số hành động mà nó sẽ phản ứng.
  • Không thể sử dụng các câu lệnh sau trong văn bản kích hoạt: THAY ĐỔI CƠ SỞ DỮ LIỆU, THAY ĐỔI THỦ TỤC, ALTER TABLE, TẠO MẶC ĐỊNH, TẠO THỦ TỤC, THAY ĐỔI THỦ TỤC, THAY ĐỔI XEM, TẠO CƠ SỞ DỮ LIỆU, TẠO QUY TẮC, TẠO Lược đồ, TẠO KÍCH HOẠT, TẠO XEM, DISK INIT, THAY ĐỔI KÍCH THƯỚC ĐĨA, CƠ SỞ DỮ LIỆU THẢ, MẶC ĐỊNH THẢ, THỦ TỤC THẢ, QUY TẮC THẢ, KÍCH HOẠT THẢ, XEM THẢ, CƠ SỞ DỮ LIỆU THẢ, NHẬT KÝ KHÔI PHỤC, CẤU HÌNH LẠI, CẬP NHẬT THỐNG KÊ.
  • Mọi thao tác SET hợp lệ chỉ hoạt động khi trình kích hoạt còn hoạt động.
  • Bạn không thể thực thi trình kích hoạt kiểm tra trạng thái của đối tượng lớn nhị phân (BLOB) của văn bản hoặc hình ảnh kiểu dữ liệu trong các cột bảng INSERTED và DELETED, bất kể quy trình có được ghi lại hay không.
  • Bạn không nên sử dụng các câu lệnh SELECT trả về các tập kết quả từ một trình kích hoạt cho một ứng dụng khách yêu cầu quản lý tập kết quả đặc biệt, cho dù việc đó có được thực hiện trong một thủ tục được lưu trữ hay không.
  • Bạn không thể tạo các trình kích hoạt INSTEAD OF UPDATE và DELETE trên các bảng có khóa ngoại với bộ tùy chọn cập nhật hoặc xóa theo tầng tương ứng.

2. Ví dụ sử dụng trigger

Ví dụ 1: Chèn và cập nhật trình kích hoạt

Những trình kích hoạt này rất hữu ích vì chúng có thể thực thi các điều kiện toàn vẹn tham chiếu và đảm bảo rằng dữ liệu là chính xác trước khi được nhập vào bảng. Trình kích hoạt thường được sử dụng để cập nhật các cột thời gian hoặc để kiểm tra dữ liệu trong các cột cụ thể theo tiêu chí bắt buộc. Nên sử dụng trình kích hoạt khi tiêu chí kiểm tra phức tạp hơn điều kiện toàn vẹn khai báo.

Trong ví dụ bên dưới, trình kích hoạt sẽ chạy bất cứ khi nào một hàng được chèn hoặc sửa đổi vào bảng Bán hàng. Nếu ngày đặt hàng không nằm trong 15 ngày đầu tháng thì hàng đó không được nhập vào bảng.

TẠO TRIGGER Tri_Ins_Sales
Đang bán
ĐỂ CHÈN, CẬP NHẬT
BẰNG
/* Khai báo các biến cục bộ cần thiết */
KHAI BÁO @nDayOfMonth TINYINT
/* Tìm thông tin về mục đã thêm */
CHỌN @nDayOfMonth = DatePart(ngày, i.ord_date)
TỪ Bán hàng, Đã chèn tôi
Ở ĐÂU s.stor_id = i.stor_id
VÀ s.ord_num = i.ord_num
VÀ s.title_id = i.title_id
/* Kiểm tra tiêu chí thất bại và, nếu cần,
gửi thông báo lỗi */
NẾU @nDayOfMonth > 15
BẮT ĐẦU
/* Lưu ý: Luôn quay lui trước. Bạn có thể không biết
loại lỗi xử lý nào đã xảy ra có thể gây ra
thời gian chặn dài vô lý */
ROLLBACK TRẦN
RAISERROR("Chỉ những đơn hàng được gửi vào ngày đầu tiên
15 ngày trong tháng”, 16, 10)
KẾT THÚC

Nếu bây giờ chúng ta cố gắng chèn hoặc cập nhật một bản ghi trong bảng, nếu điều kiện đã chỉ định không được đáp ứng, chúng ta sẽ nhận được thông báo lỗi tương ứng.

Lưu ý rằng đoạn mã truy cập vào một bảng mới và bảng này không có trong danh sách các bảng cơ sở dữ liệu. Trong trường hợp này, bảng Đã chèn chứa một bản sao của mỗi hàng, bản sao này sẽ chỉ được thêm vào nếu giao dịch hoàn tất thành công. Bảng này và các giá trị của nó được sử dụng khi thực hiện bất kỳ thao tác so sánh nào để xác minh tính hợp lệ của giao dịch.

Các cột của bảng đã chèn hoàn toàn giống với các cột của trang tính. Việc so sánh có thể được thực hiện trên cơ sở từng cột, như trong ví dụ này, trong đó các cột trong bảng Doanh số được so sánh để xác minh rằng ngày bán hàng là chính xác.

Bạn cũng có thể tạo trình kích hoạt chỉ thực hiện công việc khi một cột cụ thể được cập nhật. Để quyết định có tiếp tục xử lý trong trình kích hoạt hay không, có thể sử dụng câu lệnh IF UPDATE:

NẾU CẬP NHẬT(au_lname)
VÀ (@@ROWCOUNT=1)
BẮT ĐẦU
…
KẾT THÚC

Mã bên trong khối chỉ được thực thi nếu cột au_lname được cập nhật. Luôn nhớ rằng cột đang được cập nhật không thay đổi trong mọi trường hợp. Nếu cần có bất kỳ thay đổi nào, nhiều ứng dụng, bao gồm hầu hết các hệ thống doanh nghiệp, chỉ cần cập nhật toàn bộ hàng.

Hoạt động CẬP NHẬT ảnh hưởng đến cả hai bảng hệ thống. Bảng Đã chèn lưu trữ các giá trị mới và bảng Đã xóa lưu trữ các giá trị cũ. Vì vậy, bạn có thể sử dụng cả hai bảng này khi phân tích các thay đổi.

Thường cần phải thay thế một số giá trị bằng những giá trị không xác định. Việc này được thực hiện bằng một thao tác gán đơn giản, ví dụ:

NUM_READER = KHÔNG

Ví dụ 2: Xóa trình kích hoạt

Xóa trình kích hoạt ( xóa trình kích hoạt) thường được sử dụng trong hai trường hợp: ngăn chặn việc xóa các hàng có thể gây ra sự cố về tính toàn vẹn dữ liệu, chẳng hạn như một hàng được sử dụng làm khóa ngoại cho các bảng khác và thực hiện các thao tác xóa xếp tầng trên bảng con ( những đứa trẻ) dòng chính ( bậc thầy) dòng. Trình kích hoạt này có thể được sử dụng để xóa tất cả thông tin đặt hàng khỏi dòng bán hàng chính.

Trình kích hoạt xem xét tổng tổng của tất cả các hàng bị ảnh hưởng bởi thao tác được yêu cầu. Vì vậy, họ phải có khả năng làm việc với các kết hợp thông tin khác nhau trong bảng và trả về dữ liệu được yêu cầu. Ví dụ: khi thực thi câu lệnh DELETE FROM Authors, trình kích hoạt phải xem xét rằng câu lệnh sẽ xóa tất cả các hàng khỏi bảng.

Trong ví dụ sau, việc sử dụng biến @@ROWCOUNT sẽ ngăn chặn việc xóa nhiều hàng. Trình kích hoạt này chạy bất cứ khi nào người dùng cố gắng xóa một hàng khỏi bảng Cửa hàng. Nếu thông tin liên quan đến bán hàng thì trình kích hoạt sẽ ngăn yêu cầu được hoàn thành.

TẠO TRIGGER Tri_Del_Stores
TRÊN cửa hàng
ĐỂ XÓA
BẰNG
/* Kiểm tra số dòng sửa đổi và cấm xóa nhiều dòng cùng lúc */
NẾU @@ ROWCOUNT > 1
BẮT ĐẦU
ROLLBACK TRẦN
RAISERROR ("Mỗi lần chỉ có thể xóa một hàng.", 16, 10)
KẾT THÚC
/* Khai báo biến tạm thời để lưu thông tin bị hủy */
KHAI THÁC @ StorID char (4)
/* Lấy giá trị của hàng cần xóa */
CHỌN @StorID = d.stor_id
TỪ Cửa hàng, Đã xóa d
Ở ĐÂU s.stor_id *= d.stor_id
NẾU Tồn tại (CHỌN *
TỪ bán hàng
Ở ĐÂU stor_id = @storID)
BẮT ĐẦU
ROLLBACK TRẦN
RAISERROR ("Thông tin này không thể xóa được vì đã có mục tương ứng trong bảng Sales.", 16, 10)
KẾT THÚC

Lưu ý: Sử dụng RAISERROR là cách đơn giản nhất để gửi thông tin lỗi chi tiết và cụ thể đến quá trình gọi điện hoặc người dùng. RAISERROR cho phép chỉ định nội dung thông báo, mức độ nguy hiểm, trạng thái thông tin và kết hợp tất cả những điều này cho người dùng thành một thông báo mô tả. Hướng dẫn này cũng giúp việc viết các khối xử lý lỗi phổ biến trong ứng dụng khách trở nên dễ dàng hơn.

Ví dụ này cũng sử dụng một số câu lệnh kiểm soát giao dịch để ngừng chạy các hoạt động. Lưu ý rằng đoạn mã truy cập vào một bảng mới. Bảng này không có trong danh sách các bảng cơ sở dữ liệu. Trong trường hợp này, bảng Đã xóa chứa một bản sao của mỗi hàng, bản sao này sẽ chỉ được thêm vào nếu giao dịch hoàn tất thành công. Bảng này và các giá trị của nó được sử dụng khi thực hiện bất kỳ so sánh nào để xác minh tính hợp lệ của giao dịch.

Các cột trong bảng Đã xóa hoàn toàn giống với các cột trong bảng tính. Việc so sánh có thể được thực hiện trên cơ sở từng cột, như được minh họa trong ví dụ trong đó các cột của bảng Đã xóa được so sánh với các cột của cơ sở dữ liệu Bán hàng. Điều này sẽ đảm bảo rằng thông tin cần xóa không bao gồm dữ liệu bán hàng.

Ví dụ 3. THAY ĐỔI trigger

Các trình kích hoạt INSTEAD OF khác với các trình kích hoạt (SAU) thông thường ở chỗ chúng được thực thi không phải sau thao tác dẫn đến việc kích hoạt nó, mà thay vào đó, với tất cả các hậu quả tiếp theo, chẳng hạn như khả năng sử dụng chúng cùng với các ràng buộc toàn vẹn. Các bảng hệ thống đã chèn và đã xóa được sử dụng trong chúng giống như cách kích hoạt SAU. Phần thân kích hoạt có thể lặp lại thao tác khiến nó kích hoạt, nhưng điều này là không bắt buộc. Nói cách khác, nếu chúng ta xác định trình kích hoạt INSTEAD OF DELETE, thì không có gì ngăn cản chúng ta thực hiện thao tác DELETE trên đó, thao tác này sẽ xóa tất cả các hàng lẽ ra phải xóa theo thao tác được gọi là trình kích hoạt, nhưng chúng ta không có để làm điều này.

Hãy đưa ra một ví dụ về việc sử dụng trigger INSTEAD OF.

Bảng Công việc có mối quan hệ 1:M với bảng Nhân viên, do đó không thể xóa công việc nếu công việc đó đã được giao nhân viên. Hãy tạo một trình kích hoạt để khi một công việc bị xóa, nó sẽ kiểm tra xem nhân viên có được giao cho công việc đó hay không. Nếu được giao thì tác phẩm sẽ không bị xóa. Do có ràng buộc toàn vẹn (DRI), trình kích hoạt SAU không thể hoạt động cùng với nó. Nghĩa là, bạn có thể tạo một trình kích hoạt như thế này:


ĐỂ XÓA
BẰNG
NẾU Tồn tại (CHỌN * TỪ Nhân viên e THAM GIA Đã xóa d ON e.job_id=d.job_id)
BẮT ĐẦU
ROLLBACK TRẦN
KẾT THÚC

Nhân tiện, hãy lưu ý rằng không giống như ví dụ 2, trình kích hoạt này cho phép bạn xóa nhiều hàng cùng một lúc. Tuy nhiên, trình kích hoạt như vậy chỉ có thể hoạt động chính xác nếu kết nối giữa bảng Nhân viên và Công việc bị hỏng khiến DRI không được xử lý trước khi trình kích hoạt được thực thi.

Nhưng bạn có thể tạo trình kích hoạt INSTEAD OF:

TẠO TRIGGER Check_Job ON Jobs
THAY VÌ XÓA
BẰNG
XÓA TỪ Công việc TỪ Công việc j THAM GIA đã xóa d trên d.job_id = j.job_id
Ở ĐÂU j.job_id KHÔNG CÓ (CHỌN Job_id DISTINCT TỪ Nhân viên)

Trình kích hoạt như vậy sẽ không có xung đột với DRI và sẽ được thực thi.

Kiểm tra DRI được thực hiện ngay sau khi thực hiện thao tác, nghĩa là trước khi thực hiện kích hoạt SAU. Khi sử dụng flip-flop INSTEAD OF, về cơ bản thao tác không được thực hiện và quyền điều khiển được chuyển sang flip-flop, do đó DRI sẽ không được thực thi.

Như đã đề cập, bảng Đã chèn chứa các hàng đã thêm và bảng Đã xóa chứa các hàng đã xóa. Có thể dễ dàng đoán được rằng khi thực hiện thao tác cập nhật, cả bảng Đã chèn và bảng Đã xóa sẽ được sử dụng. Trong trường hợp này, các giá trị cũ sẽ nằm trong bảng Đã xóa và các giá trị mới sẽ nằm trong bảng Đã chèn. Bằng cách kết hợp chúng theo (các) cột khóa, không khó để xác định giá trị nào đã được thay đổi.

3. Sử dụng trình kích hoạt lồng nhau

Kích hoạt có thể được nhúng vào nhau. Cho phép 32 cấp độ lồng nhau. Nếu không muốn thực hiện các hoạt động kích hoạt lồng nhau, SQL Server có thể được cấu hình để tắt chúng.

Lưu ý: Bạn có thể kiểm tra mức lồng nhau của trình kích hoạt bất kỳ lúc nào bằng cách thăm dò giá trị được đặt trong biến @@NESTLEVEL. Nó phải nằm trong khoảng từ 0 đến 32.

Trình kích hoạt lồng nhau có thể dẫn đến đệ quy. Có hai loại đệ quy: trực tiếp và gián tiếp. Đệ quy trực tiếp xảy ra nếu việc kích hoạt một trình kích hoạt dẫn đến những thay đổi gây ra cùng một trình kích hoạt. Đệ quy gián tiếp xảy ra khi việc kích hoạt một trình kích hoạt gây ra những thay đổi khiến trình kích hoạt khác kích hoạt, từ đó dẫn đến những thay đổi khiến trình kích hoạt đầu tiên kích hoạt. Tất nhiên, chuỗi này cũng có thể bao gồm số lượng lớn hơn các trình kích hoạt.

Đệ quy trực tiếp có thể bị vô hiệu hóa (và được kích hoạt) bằng cách sử dụng tùy chọn cơ sở dữ liệu RECURSIVE_TRIGGERS. Bạn có thể tắt (và bật) đệ quy gián tiếp cũng như lồng các trình kích hoạt nói chung bằng cách sử dụng tùy chọn máy chủ trình kích hoạt lồng nhau. Tùy chọn này xác định khả năng lồng các trình kích hoạt không phải cho một cơ sở dữ liệu cụ thể mà cho toàn bộ máy chủ.

Cần lưu ý rằng các trình kích hoạt INSTEAD OF về bản chất không thể đệ quy trực tiếp.

Khi bạn tạo trình kích hoạt, SQL Server không thể nhận ra một cách độc lập rằng một số cấu trúc lồng nhau đang gây ra vòng lặp vô hạn. Thực tế như vậy chỉ có thể được thiết lập trong quá trình thực hiện trình kích hoạt này.

Giả sử rằng Table_A bao gồm một trình kích hoạt, trigger_A, được thực thi khi xảy ra cập nhật lên Table_A. Khi được thực thi, trigger_a sẽ khiến bảng Table_B được cập nhật. Bảng này bao gồm trigger_b chạy khi Table_B được cập nhật và khiến Table_A cập nhật. Do đó, nếu người dùng cập nhật một trong hai bảng này, hai bảng kích hoạt này sẽ tiếp tục khiến nhau thực thi vô thời hạn. Khi tình huống này xảy ra, SQL Server sẽ đóng hoặc hủy bỏ việc thực thi trình kích hoạt.

Hãy tưởng tượng rằng bảng Bán hàng bao gồm một trình kích hoạt và bảng Cửa hàng bao gồm một trình kích hoạt khác. Phần sau đây trình bày định nghĩa về hai trình kích hoạt lồng nhau được thực thi khi một thao tác xóa xảy ra trên bảng Bán hàng:

/* Trigger đầu tiên hủy các hàng trong bảng Stores,
nếu các hàng của bảng Bán hàng bị hủy */
TẠO TRIGGER Tri_Del_Sales
Đang bán
ĐỂ XÓA
BẰNG

IN "Trình kích hoạt xóa đang chạy cho bảng Bán hàng..."
/* Khai báo biến tạm thời để lưu trữ thông tin đã xóa */
KHAI THÁC @sStorID char(4),@sMsg varchar(40)
/* Lấy giá trị ID của hàng cần xóa */

TỪ Đã xóa


/*Xóa một dòng */
CHỌN @sMsg = "Lưu trữ " + @sStorID + " đã xóa"
IN @sMsg
XÓA KHỎI Cửa hàng
Ở ĐÂU stor_id = @sStorID
IN "Kết thúc thực hiện kích hoạt cho bảng Bán hàng"
ĐI
/* Trigger thứ hai hủy các hàng của một bảng,
nếu các hàng của hàng khác bị phá hủy */

TRÊN cửa hàng
ĐỂ XÓA
BẰNG
/* Khai báo trigger sẽ được thực thi */
IN "Trình kích hoạt xóa đang chạy cho bảng Cửa hàng..."
/* Khai báo biến tạm thời để lưu trữ thông tin
bị phá hủy khỏi bàn */
KHAI THÁC @sStorID char(4), @sMsg varchar (200)
/* Lấy giá trị bị hủy */
CHỌN HÀNG ĐẦU 1 @sStorID = stor_id
TỪ Đã xóa
/* Đã xóa là bảng phụ mà SQL Server
dùng để lưu trữ các bản ghi đã bị hủy */
NẾU @@ROWCOUNT = 0
BẮT ĐẦU
IN "Không có hàng phù hợp trong bảng Cửa hàng"
TRỞ LẠI
KẾT THÚC
/*Xóa một mục */
SELECT @sMsg = "Xóa giảm giá dành riêng cho cửa hàng" + @sStorID
IN @sMsg
XÓA giảm giá
Ở ĐÂU Stor_id = @sStorID
IN "Số lượng giảm giá đã xóa: " + CONVERT(VARCHAR(4), @@ROWCOUNT)
IN "Kết thúc thực hiện kích hoạt cho bảng Cửa hàng"

Nếu một câu lệnh DELETE được thực thi trên bảng Sales, như trong ví dụ sau, thì trình kích hoạt sẽ kích hoạt, từ đó khiến trình kích hoạt bảng Stores thực thi.

Chúng ta hãy làm:

XÓA KHỎI doanh số bán hàng Ở ĐÂU stor_id = "8042"

Kết quả:

Trình kích hoạt xóa đang chạy trên bảng Bán hàng...
Cửa hàng 8042 đã bị xóa
Trình kích hoạt xóa đang chạy trên bảng Cửa hàng...
Xóa giảm giá liên quan đến cửa hàng 8042
(1 hàng bị ảnh hưởng)
Số lượng giảm giá đã xóa: 1
Kết thúc quá trình thực thi kích hoạt cho bảng Stores
(1 hàng bị ảnh hưởng)
(4 hàng bị ảnh hưởng)
Kết thúc quá trình thực thi kích hoạt cho bảng Bán hàng

Hãy chú ý đến thứ tự của các tin nhắn được hiển thị. Đầu tiên, trình kích hoạt được kích hoạt trên bảng Bán hàng. Nó xóa một hàng khỏi bảng Stores, do đó kích hoạt nó. Hơn nữa, trên thực tế, cả bảng Sales và bảng Stroes đều chưa bị xóa (quá trình xóa đang diễn ra), điều này được chứng minh bằng việc không có thông báo máy chủ tự động (N hàng bị ảnh hưởng), xuất hiện khi xóa khỏi bất kỳ bảng nào. bảng và hiển thị có bao nhiêu hàng đã bị xóa.

Sau khi khởi chạy, trình kích hoạt trên bảng Cửa hàng sẽ xóa các hàng liên quan khỏi bảng giảm giá (Giảm giá), hiển thị thông báo (1 hàng bị ảnh hưởng). Sau đó nó in các tin nhắn thích hợp và hoàn thành công việc của nó. Ngay sau khi nó hoàn thành công việc của mình, hàng trong bảng Stores sẽ bị xóa, việc xóa này khiến nó hoạt động. Tiếp theo, vì hàng này bị xóa nên trình kích hoạt trên bảng Stores sẽ hoạt động trở lại. Trình kích hoạt này đưa ra thông báo thoát cuối cùng và thoát. Sau khi hoàn tất, thông báo (1 hàng bị ảnh hưởng) sẽ hiển thị, cho biết rằng một hàng đã bị xóa khỏi bảng Stores. Và chỉ sau đó các hàng cuối cùng mới bị xóa khỏi bảng Bán hàng.

Lưu ý: Trình kích hoạt và tính toàn vẹn tham chiếu khai báo thường không thể hoạt động cùng nhau. Ví dụ, ví dụ trước cho thấy rằng trước khi thực hiện câu lệnh DELETE, trước tiên bạn phải xóa điều kiện trên giá trị FOREIGN KEY trong bảng Giảm giá. Bất cứ khi nào có thể, nên sử dụng trình kích hoạt hoặc điều kiện toàn vẹn tham chiếu. Tuy nhiên, như đã đề cập, trình kích hoạt INSTEAD OF đã xuất hiện trong MS SQL Server 2000. Chúng có thể được sử dụng cùng với các cơ chế toàn vẹn khai báo, nhưng bạn không thể sử dụng các thao tác xếp tầng trong các kết nối cho cùng một thao tác mà trình kích hoạt INSTEAD OF đã được tạo. Ví dụ: nếu một trình kích hoạt INSTEAD OF DELETE được tạo thì bạn không thể sử dụng cấu trúc ON DELETE CASCADE trong các mối quan hệ trong đó bảng này là bảng phụ.

Ví dụ 2

Bây giờ hãy đưa ra một ví dụ về đệ quy trực tiếp trong trình kích hoạt. Hãy tạo một trình kích hoạt để khi xóa một nhân viên, nó cũng sẽ xóa những nhân viên có cùng họ hoặc tên với nhân viên đang bị xóa. Hơn nữa, khi nhân viên bị xóa bởi một trình kích hoạt, trình kích hoạt tương tự sẽ được kích hoạt lại cho thao tác xóa này và lại xóa những người có cùng họ hoặc tên, v.v.

TẠO TRIGGER Del_Emmpl_Tr TRÊN nhân viên
ĐỂ XÓA
BẰNG
NẾU Tồn tại (CHỌN * TỪ Nhân viên e
THAM GIA Đã xóa d trên e.lname = d.lname HOẶC e.Fname = d.fname)
XÓA TỪ nhân viên
TỪ Nhân viên e THAM GIA Đã xóa d trên e.lname = d.lname HOẶC e.Fname = d.fname

Không có nhân viên nào có cùng họ hoặc tên trong cơ sở dữ liệu quán rượu, nhưng bạn có thể tự thêm những nhân viên đó và kiểm tra xem điều gì sẽ xảy ra nếu bạn xóa một trong số họ. Ví dụ: để các nhân viên sau có trong cơ sở dữ liệu:

Nếu bây giờ bạn làm theo hướng dẫn:

XÓA TỪ Nhân viên Ở ĐÂU Fname = "Ivan" VÀ Lname = "Ivanov"

thì bộ kích hoạt sẽ được khởi chạy khi xóa, ngoài Ivan Ivanov, cũng sẽ xóa Ivan Sergeev và Mikhail Ivanov. Sau khi loại bỏ, trình kích hoạt sẽ được khởi chạy lại và sẽ tìm kiếm tất cả Ivanov và Mikhail, cũng như Ivanov và Sergeev. Do công việc của mình, Petr Sergeev sẽ bị loại bỏ. Sau đó, trình kích hoạt tương tự sẽ xóa Peter Vasiliev. Sau đó, cò súng sẽ tìm kiếm Petrov và Vasilyev, nhưng vì họ không còn trong bàn nên cuộc hành quyết sẽ kết thúc ở đó.

Lưu ý rằng việc kiểm tra IF EXISTS phải được thực hiện ở đây. Nếu điều này không được thực hiện thì khi xóa Peter Vasiliev, lệnh DELETE sẽ được thực thi và mặc dù nó sẽ không thực sự xóa bất kỳ ai, trình kích hoạt mới được gọi sẽ tự gọi lại (một lần nữa mà không thực sự xóa bất kỳ ai), v.v. cho đến khi vượt quá mức tối đa mức lồng nhau 32. Sau khi đạt đến mức lồng nhau 32, sẽ xảy ra lỗi và mọi hành động sẽ bị hủy.

Ví dụ 3. Đệ quy gián tiếp

Hãy thay đổi ví dụ 1 để nếu một hàng bị xóa khỏi bảng Doanh số thì cửa hàng nơi thực hiện bán hàng đã bị xóa cũng sẽ bị xóa. Vì mối quan hệ giữa các bảng này là 1:M nên có thể có nhiều doanh số bán hàng trong cửa hàng bị xóa chứ không chỉ doanh số chúng tôi đang cố xóa. Do đó, chuỗi phải như sau: xóa đợt giảm giá → xóa cửa hàng đã thực hiện đợt giảm giá đó, → xóa tất cả các đợt bán hàng khác được thực hiện trong cửa hàng này, → xóa tất cả các đợt giảm giá liên quan đến cửa hàng này. Ngoài ra, chúng ta sẽ triển khai các trigger này dưới dạng trigger INSTEAD OF để không cần phải ngắt kết nối giữa các bảng.

TẠO TRIGGER Tri_Del_Sales
Đang bán
THAY VÌ XÓA
BẰNG
DELETE FROM Sales FROM Sales s JOIN Đã xóa d trên d.ord_num = s.ord_num
NẾU Tồn tại (CHỌN * TỪ Cửa hàng s THAM GIA Đã xóa d ON d.stor_id = s.stor_id)
XÓA TỪ Cửa hàng TỪ Cửa hàng THAM GIA Đã xóa d ON d.stor_id = s.stor_id
ĐI

TẠO TRIGGER Tri_Del_Stores
TRÊN cửa hàng
THAY VÌ XÓA
BẰNG
DELETE FROM Giảm giá TỪ Giảm giá trong THAM GIA Đã xóa de trên di.stor_id=de.stor_id
IF EXISTS(SELECT * FROM Sales s JOIN Đã xóa d trên d.stor_id = s.stor_id)
XÓA TỪ Bán hàng TỪ Bán hàng s THAM GIA Đã xóa d trên d.stor_id = s.stor_id
XÓA TỪ Cửa hàng TỪ Cửa hàng THAM GIA Đã xóa d trên d.stor_id = s.stor_id

Để kiểm tra, bạn có thể chạy lệnh:

XÓA KHỎI doanh số bán hàng ở đâu ord_num = "P723"

Kết quả là không chỉ hàng có mã đơn hàng “P723” sẽ bị xóa khỏi bảng Doanh số mà còn cả 3 hàng khác liên quan đến cùng một cửa hàng (mã 8042). Bản thân cửa hàng 8042 và mức giảm giá liên quan đến nó cũng sẽ bị xóa.

Trong ví dụ trên, trong số những thứ khác, tất cả đầu ra thông báo đều bị xóa và lệnh gọi đến câu lệnh DELETE bị thay đổi do không có đầu ra thông báo, nên không cần tạo giá trị của biến cục bộ @sStroID . Việc sử dụng biến này trong câu lệnh DELETE phần nào đã hạn chế khả năng áp dụng của trigger. Do đó, trình kích hoạt trong ví dụ 2 được thiết kế để xóa bản ghi của chỉ một cửa hàng và khi xóa bản ghi liên quan đến nhiều cửa hàng cùng một lúc, chúng không hoạt động chính xác. Bây giờ không có hạn chế nào như vậy vì tất cả các bản ghi liên kết với các bản ghi trong bảng Đã xóa đều bị xóa (nghĩa là tất cả các hàng thực sự bị xóa).

Người ta có thể hỏi: tại sao lại sử dụng đệ quy? Sẽ không dễ dàng hơn khi xóa khỏi bảng Bán hàng, xóa trong trình kích hoạt trên đó tất cả các bản ghi từ chính nó có liên quan đến cùng một cửa hàng với hàng bán hàng đã xóa, sau đó xóa hàng đó khỏi bảng Cửa hàng và trong trình kích hoạt trên bảng Cửa hàng chỉ xóa các bản ghi liên quan khỏi bảng Giảm giá? Có, điều này có thể thực hiện được, nhưng chỉ khi chúng tôi luôn đưa ra lệnh xóa cụ thể khỏi bảng Bán hàng (như đã được thực hiện ở trên trong quá trình kiểm tra). Tuy nhiên, chúng ta có thể đưa ra lệnh xóa từ bảng Stores, ví dụ:

XÓA TỪ cửa hàng Ở ĐÂU stor_id = 8042

Và trong trường hợp này chúng ta cũng muốn lệnh hoạt động chính xác. Nếu trình kích hoạt trên bảng Cửa hàng, như được đề xuất trong câu hỏi, không bao gồm việc xóa khỏi Doanh số, thì nếu có doanh số bán hàng cho cửa hàng bị xóa thì việc xóa đó sẽ dẫn đến lỗi. Ví dụ của chúng tôi cho phép chúng tôi giải quyết vấn đề này. Chà, nếu trình kích hoạt trên Cửa hàng bao gồm lệnh xóa khỏi Bán hàng thì trong trình kích hoạt trên Bán hàng không cần bao gồm việc xóa doanh số bán hàng trong cùng một cửa hàng với cửa hàng đang bị xóa, vì việc này sẽ được thực hiện tự động thông qua đệ quy.

Lưu ý 1: Để ngăn chặn sự can thiệp của các trigger đã được tạo trong các ví dụ trước, bạn cần xóa chúng bằng hướng dẫn THẢ TRIGGER trigger_name.

Lưu ý 2: Một lần nữa, xin lưu ý rằng để đệ quy hoạt động, phải đặt các tùy chọn máy chủ và cơ sở dữ liệu thích hợp.

Ví dụ 4

Trong ví dụ trước, hãy xem xét trường hợp xác định một số trình kích hoạt cho một thao tác sửa đổi bảng:

TẠO TRIGGER trig_del_l TRÊN Tác giả ĐỂ XÓA NHƯ
IN "Xóa trình kích hoạt số 1"
ĐI

TẠO TRIGGER trig_del_2 TRÊN Tác giả ĐỂ XÓA NHƯ
IN "Xóa trình kích hoạt số 2"
ĐI

TẠO TRIGGER trig_upd_l TRÊN Tác giả ĐỂ CẬP NHẬT NHƯ
IN "Trình kích hoạt cập nhật số 1"
ĐI

TẠO TRIGGER trig_upd_3 TRÊN Tác giả ĐỂ CẬP NHẬT NHƯ
IN "Trình kích hoạt cập nhật #3" "
ĐI

TẠO TRIGGER trig_upd_2 TRÊN Tác giả ĐỂ CẬP NHẬT NHƯ
IN "Trình kích hoạt cập nhật số 2"
ĐI

Bây giờ hãy thử thay đổi một số mục trong bàn:

CẬP NHẬT tác giả
SET au_fname = "Yuri" Ở ĐÂU au_lname = "Tikomirov";

Tất cả ba trình kích hoạt cập nhật sẽ hoạt động:

Cập nhật trình kích hoạt số 1

Cập nhật trình kích hoạt số 3

Cập nhật trình kích hoạt số 2

Hãy chú ý đến trình tự thực hiện của trình kích hoạt: nó được xác định theo thứ tự chúng được tạo. Nếu bây giờ chúng ta xóa trigger trig_upd_3 rồi tạo lại thì khi cập nhật bảng chúng ta sẽ nhận được kết quả như sau:

Cập nhật trình kích hoạt số 1

Cập nhật trình kích hoạt số 2

Cập nhật trình kích hoạt số 3

Nhiều kích hoạt được sử dụng khá tích cực trong quá trình sao chép.

4. Hiển thị thông tin trigger và thay đổi trigger

Để tìm hiểu mục đích của trình kích hoạt của bảng, bạn phải hiển thị thông tin mô tả bất kỳ trình kích hoạt nào mà bảng sở hữu. Có một số cách để lấy thông tin về trình kích hoạt của một bảng cụ thể. Một trong số đó là SQL Server Enterprise Manager, cái còn lại là các thủ tục hệ thống sp_help và sp_depends. Để xem văn bản kích hoạt thông qua Trình quản lý doanh nghiệp, hãy làm theo các bước sau:

  1. Trong Enterprise Manager, chọn máy chủ và cơ sở dữ liệu bạn muốn làm việc.
  2. Mở bảng ở chế độ thiết kế bằng lệnh Design Table và trong cửa sổ của nó, nhấp vào nút Triggers trên thanh công cụ.
  3. Hộp thoại Tạo Trình kích hoạt sẽ xuất hiện, nơi bạn có thể xem văn bản của bất kỳ trình kích hoạt nào đã cài đặt.

Các thủ tục lưu trữ hệ thống sp_help và sp_depends đã được mô tả trong chủ đề “Thủ tục lưu trữ”.

Để thay đổi chức năng của trình kích hoạt, bạn có thể xóa nó và tạo một trình kích hoạt mới với những thay đổi phù hợp hoặc thay đổi trình kích hoạt hiện có. Để thay đổi trình kích hoạt hiện có trong T-SQL, có lệnh ALTER TRIGGER. Cú pháp của nó tương tự như lệnh CREATE TRIGGER, ngoại trừ việc nó sử dụng từ khóa ALTER thay vì CREATE.

Bạn cũng có thể thay đổi trình kích hoạt bằng Trình quản lý doanh nghiệp. Để thực hiện việc này, sau khi đăng nhập vào Enterprise Manager, bạn chỉ cần thực hiện thay đổi và áp dụng chúng.

5. Loại bỏ trình kích hoạt

Đôi khi bạn cần loại bỏ trình kích hoạt khỏi một hoặc nhiều bảng. Ví dụ: khi chuyển một ứng dụng sang phiên bản sản xuất, bạn có thể muốn loại bỏ các trình kích hoạt mang lại khả năng xử lý chất lượng cao nhưng hiệu suất bị giảm đáng kể. Bạn có thể chỉ cần xóa trình kích hoạt để thay thế chúng bằng phiên bản mới hơn. Để xóa trình kích hoạt, hãy sử dụng câu lệnh DROP TRIGGER:

THẢ TRIGGER [chủ sở hữu.]trigger_name [, n]

Việc xóa trình kích hoạt là tùy chọn nếu trình kích hoạt mới thay thế trình kích hoạt hiện có. Khi bạn xóa một bảng, tất cả các đối tượng liên kết với nó sẽ tự động bị hủy, bao gồm cả các trình kích hoạt.

Ví dụ về loại bỏ trình kích hoạt Tri_Dei_Autnors:

THẢ TRIGGER Tri_Del_Authors

6. Tạm dừng và tiếp tục kích hoạt

Thường cần phải tắt trình kích hoạt trong một khoảng thời gian mà không thực sự xóa nó. Điều này có thể đạt được bằng cách sử dụng thiết kế BẢNG THAY ĐỔI<имя_таблицы>TẮT KÍCH HOẠT<имя триггера> để vô hiệu hóa trình kích hoạt và BẢNG THAY ĐỔI<имя_таблицы>BẬT KÍCH HOẠT<имя триггера> để tiếp tục công việc của mình.

Nhiệm vụ cho công việc độc lập

Trước khi bắt đầu thực hiện các tác vụ, hãy để chúng tôi nhắc bạn rằng trình kích hoạt là các thủ tục được lưu trữ trong hệ thống được liên kết với một bảng cụ thể. Để gọi trình soạn thảo trình kích hoạt, bạn cần chọn bảng, sử dụng nút bên phải của menu ngữ cảnh để chuyển đến phần Tất cả tác vụ > Quản lý trình kích hoạt và bạn sẽ được đưa tới trình chỉnh sửa trình kích hoạt (Hình 1).

Cơm. 1. Trạng thái ban đầu của trình chỉnh sửa trình kích hoạt khi tạo trình kích hoạt mới

Nhiệm vụ 1. Phát triển một trình kích hoạt có thể xóa bản ghi về một cuốn sách nếu bản sao cuối cùng của cuốn sách này bị xóa. Bạn sẽ viết trình kích hoạt này cho bảng nào? Khi viết trình kích hoạt, hãy nhớ rằng chúng ta có bảng “Tác giả” và “Danh mục hệ thống” được liên kết với bảng “Sách”. Tuy nhiên, chúng có liên quan với nhau bằng mối quan hệ nhiều-nhiều, trong đó các bảng liên kết được sử dụng. Bạn không thể xóa dữ liệu về một cuốn sách nếu nó có liên kết trong các bảng liên kết này. Trước tiên, hãy xem xét xóa dữ liệu khỏi các bảng liên kết. Kiểm tra hoạt động của trigger này.

Nhiệm vụ 2. Phát triển một biện pháp kích hoạt không cho phép xóa bản sao của một cuốn sách nếu bản sao này hiện đang nằm trong tay người đọc. Để hủy lệnh xóa, hãy sử dụng lệnh khôi phục giao dịch ROLLBACK.

Kiểm tra hoạt động của trình kích hoạt ở chế độ độc lập bằng cách cố gắng xóa bản sao cuối cùng của cuốn sách có dấu cho biết nó thuộc quyền sở hữu của người đọc.

Cố gắng loại bỏ một bản sao của cuốn sách không có trong tay người đọc.

Kiểm tra hoạt động của hai trình kích hoạt bằng cách cố gắng xóa bản sao cuối cùng của cuốn sách trên tay người đọc.

Nhiệm vụ 3. Phát triển một cơ chế kích hoạt để kiểm soát việc phát hành sách cho độc giả và nếu số lượng sách chưa được giao trong tay vượt quá ba, sẽ không cho phép phát hành sách khác cho độc giả này.

Nhiệm vụ 4. Phát triển trình kích hoạt sẽ thêm một phiên bản khi nhập sách mới. Thật vậy, chúng tôi đã xác định rằng sách chỉ có trong danh mục của chúng tôi nếu chúng có trong thư viện của chúng tôi, do đó, khi nhập một cuốn sách mới, một bản sao của cuốn sách này phải được thêm vào bảng “Sao chép”.

Nhiệm vụ 5. Phát triển trình kích hoạt loại INSTEAD OF cho bảng “Readers”. Trình kích hoạt này sẽ kiểm tra xem có thông tin về ít nhất một trong các số điện thoại để liên lạc nhanh với đầu đọc hay không và nếu không có thông tin đó thì không nhập dữ liệu về đầu đọc.

Nhiệm vụ 6. Phát triển trình kích hoạt, khi giá trị của trường tượng trưng cho sự hiện diện của bản sao sách trong thư viện, ví dụ YES_NO, thay đổi từ “1” thành “0”, sẽ tự động thay thế các giá trị trong “Vấn đề” các trường ngày”, “Ngày trả” và “Số thẻ thư viện” "không xác định.

Nhiệm vụ 7. Phát triển trình kích hoạt không cho phép bạn xóa một người đọc nếu người đó có ít nhất một cuốn sách trong thư viện.

Nhiệm vụ 8. Phát triển một trình kích hoạt để khi một bản sao của cuốn sách bị xóa, nó sẽ kiểm tra xem cuốn sách này còn lại trong thư viện bao nhiêu bản và nếu chỉ còn lại một bản thì giá cuốn sách này sẽ tăng lên 15%. càng hiếm và có giá trị.

phiên bản in

Nền tảng SQL Server hỗ trợ chức năng cốt lõi ANSI với việc bổ sung các trình kích hoạt INSTEAD OF và kiểm tra thay đổi cột. Nền tảng này không hỗ trợ các mệnh đề THAM KHẢO và KHI. Cú pháp được đưa ra dưới đây.

(TẠO | THAY ĐỔI) TRIGGER trigger_name TRÊN table_name

(CHO | SAU | THAY THẾ) ( [,] [,] )

[…]] block_code

(TẠO | THAY ĐỔI) TRIGGER trigger_name

Tạo trình kích hoạt mới có tên trigger_name hoặc sửa đổi trigger_name trình kích hoạt hiện có bằng cách thêm hoặc thay đổi các thuộc tính của trình kích hoạt hoặc khối mã. Khi bạn sửa đổi trình kích hoạt hiện có, các quyền và phần phụ thuộc của trình kích hoạt hiện có sẽ được giữ nguyên.

TRÊN tên_bảng

Khai báo bảng hoặc dạng xem mà trigger phụ thuộc vào. Chế độ xem có thể xác định trình kích hoạt INSTEAD OF miễn là chế độ xem có thể được cập nhật và không chứa mệnh đề WITH CHECK.

VỚI MÃ HÓA

Văn bản của câu lệnh CREATE TRIGGER được mã hóa như được xác định trong bảng syscomments. Tùy chọn này rất hữu ích để bảo vệ sở hữu trí tuệ. Mệnh đề WITH ENCRYPTION ngăn việc sử dụng trình kích hoạt trong sơ đồ sao chép SQL Server.

CHO | SAU KHI THAY THẾ

Chỉ định thời điểm kích hoạt sẽ kích hoạt. (Các từ khóa FOR và AFTER đồng nghĩa với nhau.) Mệnh đề AFTER chỉ ra rằng trình kích hoạt chỉ được kích hoạt sau khi hoàn thành thành công thao tác sửa đổi dữ liệu (và các hành động xếp tầng khác cũng như kiểm tra ràng buộc). Trình kích hoạt INSTEAD OF tương tự như trình kích hoạt ANSI BEFORE ở chỗ mã kích hoạt có thể thay thế hoàn toàn thao tác sửa đổi dữ liệu. Thao tác này sẽ kích hoạt trình kích hoạt thay vì thao tác sửa đổi đã kích hoạt trình kích hoạt. Không thể sử dụng trình kích hoạt loại INSTEAD OF DELETE nếu việc xóa gây ra các hành động xếp tầng. Chỉ các trình kích hoạt INSTEAD OF mới có thể truy cập các cột TEXT, NTEXT hoặc IMAGE.

VỚI PHỤ LỤC

Một trình kích hoạt bổ sung thuộc loại hiện có sẽ được thêm vào bảng hoặc dạng xem. Hỗ trợ cho điều khoản này được cung cấp để tương thích ngược với các phiên bản trước của sản phẩm và điều khoản này chỉ có thể được sử dụng với trình kích hoạt FOR.

KHÔNG ĐỂ SAO CHÉP

Ngăn kích hoạt kích hoạt trong quá trình sửa đổi dữ liệu do hệ thống sao chép tích hợp sẵn của SQL Server khởi tạo.

NẾU CẬP NHẬT (cột) [(VÀ | HOẶC) ROATE(cột)] […]

Cho phép bạn chọn một cột cụ thể để kích hoạt trình kích hoạt. Trình kích hoạt dành riêng cho cột chỉ kích hoạt các hoạt động CẬP NHẬT và CHÈN chứ không kích hoạt các hoạt động XÓA. Nếu thao tác CẬP NHẬT hoặc CHÈN được áp dụng cho một cột không có trong danh sách thì trình kích hoạt sẽ không kích hoạt.

Nền tảng SQL Server cho phép bạn sử dụng nhiều trình kích hoạt cho một thao tác thao tác duy nhất trên một bảng hoặc dạng xem. Bằng cách này, bạn có thể sử dụng ba trình kích hoạt CẬP NHẬT trên một bảng cùng một lúc. Bạn có thể sử dụng nhiều trigger SAU trên một bảng. Thứ tự chúng được thực thi là không chắc chắn, nhưng trigger đầu tiên và trigger cuối cùng có thể được chỉ định rõ ràng bằng cách sử dụng thủ tục hệ thống được lưu trữ spsettriggerorder. Bạn chỉ có thể sử dụng một trình kích hoạt INSTEAD OF cho mỗi câu lệnh INSERT, UPDATE hoặc DELETE trên bất kỳ bảng nào.

Trong SQL Server, bạn có thể xác định bất kỳ sự kết hợp nào của trình kích hoạt trong một câu lệnh kích hoạt, được phân tách bằng dấu phẩy. (Điều này chạy cùng một mã cho mỗi lệnh trong định nghĩa kết hợp.)

Nền tảng SQL Server ngầm sử dụng biểu mẫu FOR EACH STATEMENT tiêu chuẩn ANSI cho trình kích hoạt.

Khi trình kích hoạt kích hoạt, SQL Server ghi các giá trị vào hai bảng giả quan trọng: đã xóa và đã chèn. Chúng tương ứng với các bảng giả trước và sau được mô tả trước đó trong phần Quy tắc chung của tiêu chuẩn ANSI. Các bảng này có cấu trúc giống hệt với bảng mà trình kích hoạt đã được tạo, ngoại trừ việc chúng chứa dữ liệu cũ trước thao tác sửa đổi (đã xóa) và các giá trị mới có sẵn trong bảng sau thao tác này (đã chèn).

Việc chỉ định mệnh đề AS IF UPDATE (cột) sẽ kiểm tra xem liệu thao tác INSERT hoặc UPDATE đã được thực hiện trên các cột hay chưa; Câu này tương tự như cấu trúc s/РШschschistoln của tiêu chuẩn ANSI. Bạn có thể chỉ định nhiều cột bằng cách thêm các mệnh đề riêng lẻ (cột URLOL). Nếu bạn tuân theo mệnh đề AS IF UPDATE (cột) với khối mã BEGIN...END Transact-SQL, bạn có thể thực hiện nhiều thao tác Transact-SQL trong một trình kích hoạt. Mệnh đề này có chức năng tương đương với câu lệnh IF...THEN...ELSE.

Ngoài sự can thiệp vào các hoạt động sửa đổi dữ liệu được hiển thị trong ví dụ ANSI SQL, nền tảng SQL Server cho phép các loại hoạt động khác được thực hiện trong các hoạt động sửa đổi dữ liệu. Trong ví dụ sau, chúng tôi đã quyết định rằng bảng sales_archive_2002 không còn được sử dụng nữa và bất kỳ ai cố gắng chèn dữ liệu vào bảng sẽ được thông báo về hạn chế này.

Nền tảng SQL Server không cho phép sử dụng các câu lệnh sau trong khối mã kích hoạt Transact-SQL: ALTER, CREATE, DROP, DENY, GRANT, REVOKE, LOAD, RESTORE, RECONFIGURE và TRUNCATE. Ngoài ra, các lệnh DISK và lệnh UPDA TE STA TISTICS không được phép.

Nền tảng SQL Server cho phép bạn chạy trình kích hoạt đệ quy bằng cách sử dụng tham số trình kích hoạt đệ quy của thủ tục lưu trữ hệ thống sp_dboption. Trình kích hoạt đệ quy tự kích hoạt do quá trình thực thi của chúng. Ví dụ: nếu trình kích hoạt INSERT trên bảng T1 thực hiện thao tác INSERT trên bảng T1, thì nó có thể thực hiện thao tác đệ quy. Vì trình kích hoạt đệ quy có thể nguy hiểm nên chúng bị tắt theo mặc định.

SQL Server cũng cho phép bạn sử dụng các trigger lồng nhau, lên tới 32 cấp độ lồng nhau. Nếu bất kỳ trình kích hoạt lồng nhau nào thực hiện thao tác ROLLBACK thì các trình kích hoạt tiếp theo sẽ không được kích hoạt. Ví dụ về trình kích hoạt lồng nhau: Trình kích hoạt trong bảng T1 bắt đầu một thao tác trên bảng T2, cũng có trình kích hoạt bắt đầu thao tác trên bảng TZ. Kích hoạt bị hủy nếu xảy ra vòng lặp vô hạn. Trình kích hoạt lồng nhau có thể được bật bằng cách sử dụng tham số trình kích hoạt lồng nhau của quy trình lưu trữ sp_configure. Nếu trình kích hoạt lồng nhau bị tắt, trình kích hoạt đệ quy cũng bị tắt, bất kể tham số thủ tục lưu trữ sp_dboption tương ứng.

Trong ví dụ sau, chúng tôi muốn chuyển hướng hành động của người dùng trên bảng people, đặc biệt là các giao dịch liên quan đến cập nhật, để thay vào đó, những thay đổi đối với các hàng trong bảng people được ghi vào bảng peoplejreroute. (Một dạng bảng người phức tạp hơn được hiển thị trong phần SQL Server của phần Câu lệnh CREATE/ALTER TABLE.) Trình kích hoạt cập nhật của chúng tôi sẽ ghi lại tất cả các thay đổi đối với cột 2, 3 và 4 của bảng người và ghi chúng vào bảng người. bảng peoplejreroute. Trình kích hoạt cũng sẽ ghi lại người dùng nào đã thực hiện giao dịch cập nhật và vào thời điểm nào.

Lưu ý rằng các câu lệnh SQL Server CREATE cho phép sử dụng độ phân giải tên trì hoãn. Điều này có nghĩa là lệnh được xử lý ngay cả khi nó đề cập đến một đối tượng cơ sở dữ liệu chưa tồn tại.