ver update una trigger tablas tabla sencillos para los genérico ejemplos ejemplo cambios bitacora auditoria auditar sql-server triggers information-schema

sql-server - update - triggers sql server



¿Cuál es la forma más portátil de verificar si existe un disparador en SQL Server? (9)

Estoy buscando el método más portátil para verificar la existencia de un desencadenador en MS SQL Server. Debe funcionar al menos SQL Server 2000, 2005 y preferiblemente 2008.

La información no parece estar en INFORMATION_SCHEMA, pero si está allí en alguna parte, preferiría usarla desde allí.

Yo sé de este método:

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

Pero no estoy seguro de si funciona en todas las versiones de SQL Server.


¿Los nombres de los ejecutores son forzados a ser únicos en el servidor SQL?

Como los factores desencadenantes se aplican por definición a una tabla específica, ¿no sería más eficaz restringir la búsqueda solo a la tabla en cuestión?

Tenemos una base de datos con más de 30k tablas en todas las cuales tienen al menos un disparador y pueden tener más (diseño de base de datos defectuoso, muy probablemente, pero tuvo sentido hace años y no se escalaron bien)

yo suelo

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


Además de la excelente respuesta de marc_s:

si la comprobación de existencia está prevista antes de descartar o modificar el desencadenador de alguna manera, utilice un TSQL directo try/Catch bock, como el más rápido significa.

Por ejemplo:

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;

El mensaje de error será

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

Luego, simplemente verifique si el resultado ejecutado arrojó filas o no, lo cual es fácil tanto en sql directo como en las API programáticas (C #, ...).


Esto funciona en SQL Server 2000 y superior

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

Tenga en cuenta que el ingenuo converse no funciona de manera confiable:

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

... porque si el objeto no existe, OBJECTPROPERTY devuelve NULL , y NULL es (por supuesto) no <> 1 (o cualquier otra cosa).

En SQL Server 2005 o posterior, podría usar COALESCE para tratar con eso, pero si necesita soportar SQL Server 2000, tendrá que estructurar su declaración para tratar con los tres posibles valores de retorno: NULL (el objeto no lo hace) existe en absoluto), 0 (existe pero no es un disparador), o 1 (es un disparador).


Generado por 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 ...

Para select @@version

Microsoft SQL Server 2008 R2 (RTM) - 10.50.1797.0 (X64) 1 de junio de 2011 15:43:18 Copyright (c) Microsoft Corporation Enterprise Edition (64 bits) en Windows NT 6.1 (Build 7601: Service Pack 1) (Hipervisor )


Probado y no funciona en SQL Server 2000:

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

Probado y funciona bien en SQL Server 2000 y SQL Server 2005:

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


Si está tratando de encontrar un DDL Trigger con un servidor en SQL Server 2014, debe probar sys.server_triggers.

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

Si le dije a tou algo incorrecto, por favor avíseme.

Editar: No revisé este dm en otras versiones de SQL Server.


Suponiendo que es un desencadenador DML:

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

Para otros tipos de objetos (tablas, vistas, claves, lo que sea ...), consulte: http://msdn.microsoft.com/en-us/library/ms190324.aspx en ''type''.


También está la vista preferida del catálogo "sys.triggers":

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

o llame al proc almacenado sp_Helptrigger:

exec sp_helptrigger ''MyTableName''

Pero aparte de eso, creo que eso es todo :-)

Bagazo

Actualización (para Jakub Januszkiewicz):

Si necesita incluir la información del esquema, también podría hacer algo como esto:

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


Usaría esta sintaxis para verificar y soltar el disparador

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]