什么是检查SQL Server中是否存在触发器的最便捷的方法?
我正在寻找最便携的方法来检查在MS SQL Server中的触发器的存在。 它至less需要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版本。
这适用于SQL Server 2000及更高版本
IF OBJECTPROPERTY(OBJECT_ID('{your_trigger}'), 'IsTrigger') = 1 BEGIN ... END
请注意,天真的交谈不能可靠地工作:
-- This doesn't work for checking for absense IF OBJECTPROPERTY(OBJECT_ID('{your_trigger}'), 'IsTrigger') <> 1 BEGIN ... END
…因为如果对象根本不存在, OBJECTPROPERTY
返回NULL
,而NULL
(当然)不是<> 1
(或其他)。
在SQL Server 2005或更高版本中,可以使用COALESCE
来处理这个问题,但是如果您需要支持SQL Server 2000,则必须构造语句来处理三个可能的返回值: NULL
(该对象不存在), 0
(它存在但不是一个触发器),或1
(这是一个触发器)。
还有一些首选的“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
假设它是一个DML触发器:
IF OBJECT_ID('your_trigger', 'TR') IS NOT NULL BEGIN PRINT 'Trigger exists' END ELSE BEGIN PRINT 'Trigger does not exist' END
对于其他types的对象(表,视图,键,无论…),请参阅:“types”下的http://msdn.microsoft.com/en-us/library/ms190324.aspx 。
经过testing,在SQL Server 2000上不起作用:
select * from sys.triggers where name = 'MyTrigger'
在SQL Server 2000和SQL Server 2005上testing并正常工作:
select * from dbo.sysobjects where name = 'MyTrigger' and OBJECTPROPERTY(id, 'IsTrigger')
除了marc_s的优秀答案:
如果存在检查是在以某种方式丢弃或修改触发器之前进行的,则使用直接的TSQL try/Catch
bock作为最快的方法。
例如:
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;
错误消息将是
Cannot drop the trigger 'MyTableAfterUpdate', because it does not exist or you do not have permission.
然后简单地检查Executed Result是否返回行,这在直接sql以及编程API(C#,…)中很容易。
触发器名称在SQL Server中被强制为唯一的吗?
由于触发器是根据定义应用于特定的表,所以将search限制在仅有的表中是不是更有效率?
我们有一个超过30k表的数据库,其中至less有一个触发器,可能会有更多(糟糕的数据库devise – 很可能,但它在几年前是有道理的,并没有很好地扩展)
我用
SELECT * FROM sys.triggers WHERE [parent_id] = OBJECT_ID(@tableName) AND [name] = @triggerName
我会用这个语法来检查和删除触发器
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]
如果您正在尝试在SQL Server 2014上查找服务器作用域DDL触发器,则应尝试使用sys.server_triggers。
IF EXISTS (SELECT * FROM sys.server_triggers WHERE name = 'your trigger name') BEGIN {do whatever you want here} END
如果我告诉任何不正确的东西,请告诉我。
编辑:我没有在另一个版本的SQL Server上检查这个DM。
由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 ...
对于select @@version
Microsoft Windows Server 2008 R2(RTM) – 10.50.1797.0(X64)Jun 1 2011 15:43:18在Windows NT 6.1(Build 7601:Service Pack 1)上的Microsoft Corporation企业版(64位) )