49

我正在寻找最便携的方法来检查 MS SQL Server 中是否存在触发器。它至少需要在 SQL Server 2000、2005 和最好是 2008 上运行。

该信息似乎不在 INFORMATION_SCHEMA 中,但如果它在某处,我更愿意从那里使用它。

我确实知道这种方法:

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

end

但我不确定它是否适用于所有 SQL Server 版本。

4

9 回答 9

63

还有首选的“sys.triggers”目录视图:

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

或调用 sp_Helptrigger 存储过程:

exec sp_helptrigger 'MyTableName'

但除此之外,我想就是这样:-)

马克

更新(对于 Jakub Januszkiewicz):

如果您需要包含架构信息,您还可以执行以下操作:

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
于 2009-03-11T21:33:46.980 回答
34

This works on SQL Server 2000 and above

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

Note that the naive converse doesn't work reliably:

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

...because if the object doesn't exist at all, OBJECTPROPERTY returns NULL, and NULL is (of course) not <> 1 (or anything else).

On SQL Server 2005 or later, you could use COALESCE to deal with that, but if you need to support SQL Server 2000, you'll have to structure your statement to deal with the three possible return values: NULL (the object doesn't exist at all), 0 (it exists but is not a trigger), or 1 (it's a trigger).

于 2010-08-05T14:40:19.213 回答
9

Assuming it is a DML trigger:

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

For other types of objects (tables, views, keys, whatever...), see: http://msdn.microsoft.com/en-us/library/ms190324.aspx under 'type'.

于 2011-11-12T23:27:35.827 回答
2

Tested and doesn't work on SQL Server 2000:

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

Tested and works ok on SQL Server 2000 and SQL Server 2005:

select * from dbo.sysobjects
where name = 'MyTrigger' and OBJECTPROPERTY(id, 'IsTrigger')
于 2009-04-09T09:03:43.073 回答
2

In addition to the excellent answer by marc_s:

if the existence check is intended prior to dropping or modifying the trigger in some way, use a direct TSQL try/Catch bock, as the fastest means.

For instance:

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;

The Error Message will be

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

Then simply check if the Executed Result returned rows or not, which is easy in direct sql as well as the programmatic APIs (C#,...).

于 2013-12-08T12:29:53.960 回答
2

If you're trying to find a server scoped DDL Trigger on SQL Server 2014, you should try sys.server_triggers.

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

If I told tou anything incorrect, please let me know.

Edit: I didn't check for this dm on another versions of SQL Server.

于 2014-07-16T17:31:20.497 回答
1

Are trigger names forced to be unique in SQL server?

As triggers are by definition applied to a specific table would it not be more efficient to restrict the search to only the table in question?

We have a database with over 30k tables in it all of which have at least one trigger and may have more (bad DB design - quite probably, but it made sense years ago and didn't scale well)

I use

SELECT * FROM sys.triggers 
WHERE [parent_id] = OBJECT_ID(@tableName) 
AND [name] = @triggerName
于 2013-02-04T10:58:04.573 回答
1

I would use this syntax to check and drop trigger

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]
于 2014-01-15T08:09:41.460 回答
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  
...

For select @@version

Microsoft SQL Server 2008 R2 (RTM) - 10.50.1797.0 (X64) Jun 1 2011 15:43:18 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 (Build 7601: Service Pack 1) (Hypervisor)

于 2016-02-24T11:20:03.490 回答