Was ist die portable Möglichkeit zu überprüfen, ob ein Trigger in SQL Server vorhanden ist?

StackOverflow https://stackoverflow.com/questions/636452

Frage

Ich interessiere mich für die die meisten tragbaren Verfahren zur Existenz eines Triggers in MS SQL Server zu überprüfen. Es muss zumindest auf SQL Server 2000, 2005 und vorzugsweise 2008 arbeiten.

Die Information erscheint nicht in INFORMATION_SCHEMA zu sein, aber wenn es irgendwo da drin ist, würde ich es vorziehen, es zu benutzen, von dort aus.

Ich weiß diese Methode:

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

end

Aber ich bin nicht sicher, ob es auf all SQL Server-Versionen funktioniert.

War es hilfreich?

Lösung

Dies funktioniert auf SQL Server 2000 und höher

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

Beachten Sie, dass die naive Umkehrung nicht erwartungs:

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

... weil, wenn das Objekt überhaupt nicht existieren, OBJECTPROPERTY NULL zurückgibt, und NULL ist (natürlich) nicht <> 1 (oder etwas anderes).

Auf SQL Server 2005 oder höher, könnten Sie COALESCE verwenden damit zu umgehen, aber wenn Sie SQL Server 2000 unterstützen müssen, müssen Sie Ihre Aussage strukturieren mit den drei möglichen Rückgabewerte zu behandeln: NULL (das Objekt gar nicht) vorhanden sind, 0 (es existiert, aber kein Trigger) oder 1 (es ist ein Trigger).

Andere Tipps

Es gibt auch die bevorzugte "sys.triggers" Katalogsicht:

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

oder rufen Sie die sp_Helptrigger gespeicherte Prozedur:

exec sp_helptrigger 'MyTableName'

Aber anders als das, ich denke, das ist es: -)

Marc

Update (für Jakub Januszkiewicz):

Wenn Sie das Schema Informationen enthalten müssen, können Sie auch etwas tun:

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

Unter der Annahme, es wird ein DML-Trigger:

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

Für andere Arten von Objekten (Tabellen, Views, Schlüssel, was auch immer ...) finden Sie unter: http :. //msdn.microsoft.com/en-us/library/ms190324.aspx unter 'Typ'

Getestet und funktioniert nicht auf SQL Server 2000:

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

Getestet und funktioniert ok auf SQL Server 2000 und SQL Server 2005:

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

Neben der ausgezeichneten Antwort von marc_s:

, wenn die Existenzprüfung ist vor soll fallen zu lassen oder den Auslöser in irgendeiner Weise zu modifizieren, verwenden Sie einen direkten TSQL try/Catch bock, wie die schnellste.

Zum Beispiel:

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;

Die Fehlermeldung wird

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

Dann einfach überprüfen, ob die Ausgeführt Ergebniszeilen zurückgegeben oder nicht, die in direktem SQL einfach ist, wie auch die programmatischen APIs (C #, ...).

Triggernamen eindeutig in SQL Server sein gezwungen?

Als Auslöser per Definition auf eine bestimmte Tabelle angewandt werden, wäre es nicht effizienter sein, um die Suche einzuschränken, um nur die Tabelle in Frage?

Wir haben eine Datenbank mit über 30k Tabellen in allem, von denen mindestens einen Trigger haben und kann mehr (sehr schlecht DB-Design - sehr wahrscheinlich, aber es machte vor Sinne Jahren und skalieren nicht gut)

ich

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

Ich würde diese Syntax verwenden, um Trigger zu überprüfen und fallen

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]

Wenn Sie versuchen, einen Server scoped DDL-Trigger auf SQL Server 2014 zu finden, sollten Sie sys.server_triggers versuchen.

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

Wenn ich tou etwas nicht in Ordnung, sagte lass es mich wissen.

Edit: Ich habe überprüfe nicht für diese dm auf einem anderen Versionen von SQL Server.

über 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  
...

Für select @@version

  

Microsoft SQL Server 2008 R2 (RTM) - 10.50.1797.0 (X64) 1. Juni 2011   15.43.18 Copyright (c) Microsoft Corporation Enterprise Edition   (64-Bit) unter Windows NT 6.1 (Build 7601: Service Pack 1)   (Hypervisor)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top