[英]What is the most portable way to check whether a trigger exists in SQL Server?
我正在尋找最便攜的方法來檢查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版本。
還有首選的“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
這適用於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
(它是一個觸發器)。
假設它是DML觸發器:
IF OBJECT_ID('your_trigger', 'TR') IS NOT NULL
BEGIN
PRINT 'Trigger exists'
END
ELSE
BEGIN
PRINT 'Trigger does not exist'
END
對於其他類型的對象(表,視圖,鍵,等等......),請參閱:“類型”下的http://msdn.microsoft.com/en-us/library/ms190324.aspx 。
除了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 2000上運行:
select * from sys.triggers where name = 'MyTrigger'
在SQL Server 2000和SQL Server 2005上測試並正常工作:
select * from dbo.sysobjects
where name = 'MyTrigger' and OBJECTPROPERTY(id, 'IsTrigger')
觸發器名稱是否在SQL Server中被強制為唯一?
由於根據定義將觸發器應用於特定表格,將搜索限制為僅限於相關表格會不會更有效率?
我們有一個包含超過30k表的數據庫,所有這些表都至少有一個觸發器,可能有更多(糟糕的數據庫設計 - 很可能,但它在幾年前才有意義並且不能很好地擴展)
我用
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
如果我告訴tou任何不正確的,請告訴我。
編輯:我沒有在其他版本的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 SQL Server 2008 R2(RTM) - 10.50.1797.0(X64)2011年6月1日15:43:18版權所有(c)Microsoft Corporation企業版(64位)在Windows NT 6.1(Build 7601:Service Pack 1)上(管理程序) )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.