Trình kích hoạt T-SQL để cập nhật các cột


7

Tôi đã làm việc với các truy vấn SQL trong một vài tuần và tôi đang cố gắng học hỏi và hiểu từ những sai lầm của mình. Tôi có một bảng có hai cột IsInvisible (bit)ShortName (string)khi một cột được thay đổi để cập nhật một cột khác cũng như: - nếu được thêm a ~ trước ShortName để đặt IsInvisiblethành 1 và nếu ~ bị xóa để đặt thành 0 - nếu IsInvisibleđược đặt thành 0 1 để thêm ~ phía trước Tên ngắn và khi được đặt thành 0 để xóa nó.

Tôi đã thử một cái gì đó như:

ALTER TRIGGER [dbo].[updateInvisibility]
ON [dbo].[table]
AFTER UPDATE
AS
BEGIN

UPDATE t
SET IsInvisible = (CASE WHEN i.ShortName like '~%' THEN 1 ELSE 0 END),
    ShortName = (CASE WHEN i.IsInvisible = 1 AND t.ShortName NOT LIKE '~%'
                 THEN '~' + t.ShortName
                 ELSE t.ShortName
            END)
FROM table t JOIN
     inserted i
     ON t.Id = i.Id;

end

Vấn đề của tôi là khi tôi cập nhật một trong hai cột hoặc cả hai, không có gì xảy ra và tôi gặp lỗi này:

Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32)

Tôi đang làm gì sai?

Tùy chọn "Cho phép kích hoạt để bắn người khác" hiển thị "Đúng".


Bạn có bất kỳ kích hoạt khác trên bảng này?
Shaulinator

Câu trả lời:


10

Đây là vấn đề:

  1. Bạn cập nhật bảng
  2. Nó kích hoạt trình kích hoạt cập nhật: updateInvisibility
  3. Trong trình kích hoạt, bạn cập nhật lại bảng để nó kích hoạt trình updateInvisibilitykích hoạt

và sau đó nó tiếp tục làm điều đó để bạn kết thúc việc kích hoạt nhiều lần theo kiểu đệ quy mà không hề nhận ra. Máy chủ SQL sẽ cho phép cuộc gọi lồng nhau này sâu 32 cấp và sau đó nó sẽ ném lỗi này:

Quá trình lưu trữ tối đa, chức năng, kích hoạt hoặc xem mức lồng nhau vượt quá (giới hạn 32)

đó là khá rõ ràng.

Giải pháp T-SQL

Giải pháp chỉ dành cho mã là kiểm tra mức lồng nhau và để lại nếu lớn hơn 1 (1 là lần đầu tiên nó được gọi bởi bản cập nhật):

IF TRIGGER_NESTLEVEL() > 1 RETURN;

Như thế này:

ALTER TRIGGER [dbo].[updateInvisibility]
ON [dbo].[table]
AFTER UPDATE
AS
BEGIN
    IF TRIGGER_NESTLEVEL() > 1 RETURN;

    -- Do your work...
END

Thay thế

Như được chỉ ra trong một nhận xét của RBarryYoung , bạn có thể ngăn chặn vấn đề này ngay từ đầu bằng cách vô hiệu hóa các kích hoạt đệ quy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.