2015-06-25 14 views
10

Tôi muốn kiểm tra xem trình kích hoạt có tồn tại trên [tbl] hay không và tạo một trình kích hoạt khác. Tôi đã thử nó theo cách này nhưng không hoạt động. Tôi đang làm gì sai?trình kích hoạt thả nếu tồn tại và tạo

IF EXISTS (SELECT * FROM sys.objects WHERE [name] = '[dbo].[trg]' AND [type] = 'TR') 
     DROP TRIGGER [dbo].[trg] ON [dbo].[tbl] 
GO 
CREATE TRIGGER [dbo].[trg] ON [dbo].[tbl] 
AFTER DELETE 
AS 
BEGIN 
    // 
END 
GO 

Trả lời

22

Các [name] trường trong sys.objects sẽ chỉ chứa tên thực tế (ví dụ: trg), không bao gồm các lược đồ (ví dụ: dbo trong trường hợp này) hoặc bất kỳ vòng loại văn bản (ví dụ: [] trong trường hợp này).

VÀ, bạn không chỉ định tên bảng cho DROP TRIGGER vì trình kích hoạt là một đối tượng của chính nó (không giống như chỉ mục). Vì vậy, bạn cần phải loại bỏ mệnh đề ON (chỉ được sử dụng với các kích hoạt DDL và Logon).

IF EXISTS (SELECT * FROM sys.objects WHERE [name] = N'trg' AND [type] = 'TR') 
BEGIN 
     DROP TRIGGER [dbo].[trg]; 
END; 

Xin lưu ý rằng bạn nên tiền tố chuỗi tên đối tượng theo nghĩa đen với một N kể từ khi lĩnh vực [name] là một datatype sysname đó tương đương với NVARCHAR(128).

Nếu bạn muốn kết hợp với tên sơ đồ, bạn có thể sử dụng OBJECT_ID() chức năng mà không cho phép tên lược đồ và vòng loại văn bản (sau đó bạn sẽ cần phải phù hợp với object_id thay vì name):

IF EXISTS (SELECT * FROM sys.objects WHERE [object_id] = OBJECT_ID(N'[dbo].[trg]') 
       AND [type] = 'TR') 
BEGIN 
     DROP TRIGGER [dbo].[trg]; 
END; 

Và để đơn giản hóa, vì tên đối tượng cần phải là duy nhất trong lược đồ, bạn thực sự chỉ cần kiểm tra sự tồn tại của nó. Nếu vì lý do nào đó, một loại đối tượng khác nhau tồn tại với tên đó, thì DROP TRIGGER sẽ không thành công vì đối tượng kia là, tốt, không phải là trình kích hoạt ;-). Do đó, tôi sử dụng như sau:

IF (OBJECT_ID(N'[dbo].[trg]') IS NOT NULL) 
BEGIN 
     DROP TRIGGER [dbo].[trg]; 
END; 
+0

hi scrutzky. Tôi gặp lỗi: Cú pháp không chính xác gần 'dbo'. Đã có một đối tượng có tên 'trg' trong cơ sở dữ liệu. – user3399326

+0

@ user3399326 Tôi vừa cập nhật câu trả lời của mình để giải quyết lỗi đó. Đây là mệnh đề 'ON' của' DROP TRIGGER' đang gây ra nó. –

+0

@scurtzky: nó cuối cùng đã hoạt động. cảm ơn rất nhiều!! – user3399326

0

Bạn có thể thử

SELECT * FROM sys.objects WHERE [name] = PARSENAME('[dbo].[trg]',1) AND [type] = 'TR' 

EDIT:

Vâng srutzky đã đưa cho bạn câu trả lời và giải thích tốt, bạn có thể phân tích cú pháp tên với sự giúp đỡ của PARSENAME.

+0

Tại sao phải làm phiền với tên phân tách? Chỉ cần loại bỏ lược đồ. :) –

+0

@SeanLange Đúng, chỉ một chút thông tin bổ sung sẽ không bị tổn thương =) – mxix

Các vấn đề liên quan