Was ist die portable Möglichkeit zu überprüfen, ob ein Trigger in SQL Server vorhanden ist?
-
10-07-2019 - |
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.
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)