2009-03-11 33 views
46

Tôi đang tìm phương thức di động nhất để kiểm tra sự tồn tại của trình kích hoạt trong MS SQL Server. Nó cần phải làm việc trên ít nhất SQL Server 2000, 2005 và tốt nhất là 2008.Cách di động nào nhất để kiểm tra xem trình kích hoạt có tồn tại trong SQL Server không?

Thông tin không xuất hiện trong INFORMATION_SCHEMA, nhưng nếu nó ở trong một nơi nào đó, tôi muốn sử dụng nó từ đó.

tôi biết của phương pháp này:

if exists (
    select * from dbo.sysobjects 
    where name = 'MyTrigger' 
    and OBJECTPROPERTY(id, 'IsTrigger') = 1 
) 
begin 

end 

Nhưng tôi không chắc liệu nó hoạt động trên tất cả các phiên bản SQL Server.

Trả lời

34

này hoạt động trên SQL Server 2000 trở lên

IF OBJECTPROPERTY(OBJECT_ID('{your_trigger}'), 'IsTrigger') = 1 
BEGIN 
    ... 
END 

Lưu ý rằng ngược lại ngây thơ không hoạt động đáng tin cậy:

-- This doesn't work for checking for absense 
IF OBJECTPROPERTY(OBJECT_ID('{your_trigger}'), 'IsTrigger') <> 1 
BEGIN 
    ... 
END 

... bởi vì nếu đối tượng không tồn tại ở tất cả, OBJECTPROPERTY trả về NULLNULL là (tất nhiên) không phải là <> 1 (hoặc bất kỳ thứ gì khác).

Trên SQL Server 2005 hoặc mới hơn, bạn có thể sử dụng COALESCE để giải quyết vấn đề đó, nhưng nếu bạn cần hỗ trợ SQL Server 2000, bạn sẽ phải cấu trúc câu lệnh của mình để xử lý ba giá trị trả về: NULL đối tượng không tồn tại ở tất cả), 0 (nó tồn tại nhưng không phải là một kích hoạt), hoặc 1 (nó là một kích hoạt).

+2

[Quan trọng caveat] (https://msdn.microsoft.com/en-us/library/ms190328 (v = sql.100) .aspx): "* Đối tượng không được lược đồ phạm vi, chẳng hạn như trình kích hoạt DDL, không thể được truy vấn bằng cách sử dụng OBJECT_ID. * "Cách giải quyết trong các trường hợp này là sử dụng khung nhìn' sys.triggers' như là @marc_s mô tả trong câu trả lời của anh ta. – mwolfe02

60

Ngoài ra còn có các ưu tiên "sys.triggers" Danh mục xem:

select * from sys.triggers where name = 'MyTrigger' 

hoặc gọi sp_Helptrigger proc lưu trữ:

exec sp_helptrigger 'MyTableName' 

Nhưng khác hơn thế, tôi đoán đó là về nó :-)

Marc

Cập nhật (dành cho Jakub Januszk) iewicz):

Nếu bạn cần phải bao gồm các thông tin lược đồ, bạn cũng có thể làm điều gì đó như thế này:

SELECT 
    (list of columns) 
FROM sys.triggers tr 
INNER JOIN sys.tables t ON tr.parent_id = t.object_id 
WHERE t.schema_id = SCHEMA_ID('dbo') -- or whatever you need 
+0

'select * from sys.triggers trong đó name = 'MyTrigger'' không hoạt động cho trình kích hoạt (hoạt động chính xác, v.v.) của tôi, trong khi' IF OBJECTPROPERTY của wgw (OBJECT_ID (' {your_trigger} '),' IsTrigger ') = 1' hiện ... MSSQL 2008 R2. –

+0

@JakubJanuszkiewicz: bạn có đang ở đúng DB khi bạn chạy chương trình này không ?? 'sys.triggers' luôn hiển thị trigger trong DB hiện tại của bạn - nó không hiển thị tất cả các trigger từ tất cả các cơ sở dữ liệu ... –

+0

@ marc-s: Tôi đã ở đúng DB. Tôi đã tìm thấy vấn đề - cột 'name' trong' sys.triggers' chỉ là tên (không có tên lược đồ), trong khi 'OBJECT_ID ('...')' mong đợi một tên đủ điều kiện lược đồ (ít nhất là nếu lược đồ nếu một cái không mặc định, nếu tôi hiểu nó đúng).Vì vậy, sau khi tôi đã sao chép 'OBJECT_ID ('MySchema.MyTrigger') đang hoạt động' 'vào' select * từ sys.triggers', nó không hoạt động. Lọc chỉ bằng 'MyTrigger' hoạt động tốt. –

2

Tested và không hoạt động trên SQL Server 2000:

select * from sys.triggers where name = 'MyTrigger' 

Đã kiểm tra và hoạt động ok trên SQL Server 2000 và SQL Server 2005:

select * from dbo.sysobjects 
where name = 'MyTrigger' and OBJECTPROPERTY(id, 'IsTrigger') 
+1

FWIW, 'select * của bạn từ dbo.sysobjects nơi name = 'MyTrigger' và OBJECTPROPERTY (id, 'IsTrigger')' không hoạt động cho chức năng của tôi đúng sau khi chèn, xóa kích hoạt trên SQL-2000. Hàng nằm trong 'sysobjects', nhưng' OBJECTPROPERTY (id, 'IsTrigger') 'trên ID của nó (như một phần của phần trên hoặc riêng biệt chỉ sử dụng ID thô của nó) cho' 0'. Việc kiểm tra 'xtype = 'TR'' hoặc' type =' TR'' hoạt động. –

9

Giả sử nó là một kích hoạt DML:

IF OBJECT_ID('your_trigger', 'TR') IS NOT NULL 
BEGIN 
    PRINT 'Trigger exists' 
END 
ELSE 
BEGIN 
    PRINT 'Trigger does not exist' 
END 

Đối với các loại đối tượng (bảng biểu, quan điểm, chìa khóa, bất cứ điều gì ...), xem: http://msdn.microsoft.com/en-us/library/ms190324.aspx trong 'type'.

+1

Điều này kiểm tra bất kỳ loại đối tượng, không chỉ gây nên. –

+0

nó in 'Kích hoạt tồn tại', hoạt động trong máy chủ sql 2012 – stom

1

Tên trình kích hoạt có phải là duy nhất trong máy chủ SQL không?

Vì trình kích hoạt theo định nghĩa được áp dụng cho một bảng cụ thể, sẽ không hiệu quả hơn khi hạn chế tìm kiếm chỉ với bảng được đề cập?

Chúng tôi có một cơ sở dữ liệu với hơn 30k bảng trong nó tất cả trong đó có ít nhất một kích hoạt và có thể có nhiều (thiết kế DB xấu - hoàn toàn có thể, nhưng nó có ý nghĩa năm trước và không quy mô tốt)

tôi sử dụng

SELECT * FROM sys.triggers 
WHERE [parent_id] = OBJECT_ID(@tableName) 
AND [name] = @triggerName 
2

Ngoài câu trả lời tuyệt vời bởi marc_s:

nếu kiểm tra sự tồn tại được thiết kế trước khi thả lại hay điều chỉnh kích hoạt một cách nào đó, sử dụng một TSQL trực tiếp try/Catch bock, như là phương tiện nhanh nhất.

Ví dụ:

BEGIN TRY 
    DROP TRIGGER MyTableAfterUpdate; 
END TRY 
BEGIN CATCH 
    SELECT ERROR_NUMBER() AS erno WHERE erno = 3701; -- may differ in SQL Server < 2005 
END CATCH; 

được thông báo lỗi sẽ

Cannot drop the trigger 'MyTableAfterUpdate', because it does not exist or you do not have permission. 

Sau đó chỉ cần kiểm tra xem các kết quả đã thi lại hàng hay không, đó là dễ dàng trong sql trực tiếp cũng như các API theo chương trình (C#, ...).

1

Tôi sẽ sử dụng cú pháp này để kiểm tra và thả cò

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[SCHEMA_NAME].[TRIGGER_NAME]') AND type in (N'TR')) 
DROP TRIGGER [SCHEMA_NAME].[TRIGGER_NAME] 
1

Nếu bạn đang cố gắng tìm một máy chủ scoped DDL Trigger trên SQL Server 2014, bạn nên cố gắng sys.server_triggers.

IF EXISTS (SELECT * FROM sys.server_triggers WHERE name = 'your trigger name') 
BEGIN 
    {do whatever you want here} 
END 

Nếu tôi nói với bạn điều gì không chính xác, vui lòng cho tôi biết.

Chỉnh sửa: Tôi đã không kiểm tra dm này trên một phiên bản khác của SQL Server.

0

Generated by Sql Server Management Studio:

IF EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[RolesYAccesos2016_UsuariosCRM_trgAfterInsert]')) 
DROP TRIGGER [dbo].[RolesYAccesos2016_UsuariosCRM_trgAfterInsert] 
GO 


CREATE TRIGGER [dbo].[RolesYAccesos2016_UsuariosCRM_trgAfterInsert] 
ON [PortalMediadores].[dbo].[RolesYAccesos2016.UsuariosCRM] 
FOR INSERT 
AS 
... 

Đối select @@version

Microsoft SQL Server 2008 R2 (RTM) - 10.50.1797.0 (X64) ngày 01 Tháng 6 2011 15:43 : 18 Bản quyền (c) Microsoft Corporation Enterprise Edition (64-bit) trên Windows NT 6.1 (Phiên bản 7601: Gói Dịch vụ 1) (Hypervisor)

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