Pergunta

Eu estou procurando o mais portátil método para verificar se há existência de um gatilho em MS SQL Server. Ele precisa trabalhar em pelo menos SQL Server 2000, 2005 e de preferência de 2008.

As informações não parece estar em INFORMATION_SCHEMA, mas se ele está em algum lugar, eu preferiria usá-lo de lá.

Eu sei deste método:

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

end

Mas eu não tenho certeza se ele funciona em todas as versões do SQL Server.

Foi útil?

Solução

Isso funciona em SQL Server 2000 e acima

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

Note que o inverso ingênuo não funciona de forma confiável:

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

... porque se o objeto não existir, OBJECTPROPERTY retornos NULL e NULL é (obviamente) não <> 1 (ou qualquer outra coisa).

No SQL Server 2005 ou mais tarde, você poderia usar COALESCE Para lidar com isso, mas se você precisa para suportar o SQL Server 2000, você terá que estruturar sua declaração de lidar com os três valores de retorno possíveis: NULL (o objeto não existe em tudo), 0 (ela existe, mas não é um gatilho), ou 1 (é um gatilho).

Outras dicas

Há também o "sys.triggers" catálogo vista preferida:

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

ou ligue para o sp_Helptrigger armazenados proc:

exec sp_helptrigger 'MyTableName'

Mas além disso, eu acho que é sobre ele: -)

Marc

Update (para Jakub Januszkiewicz):

Se você precisa incluir as informações de esquema, você também poderia fazer algo parecido com isto:

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

Assumindo que é um gatilho DML:

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

Para outros tipos de objetos (tabelas, vistas, chaves, o que quer ...), ver: http :. //msdn.microsoft.com/en-us/library/ms190324.aspx sob 'tipo'

Testado e não funciona no SQL Server 2000:

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

Testado e funciona ok no SQL Server 2000 e SQL Server 2005:

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

Além da excelente resposta por marc_s:

Se o Verificar existência é destinado antes de deixar cair ou modificar o gatilho, de alguma forma, usar um TSQL try/Catch bock direta, como o meio mais rápido.

Por exemplo:

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;

A mensagem de erro será

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

Em seguida, basta verificar se o resultado Executado voltou linhas ou não, que é fácil em sql directo, bem como as APIs programáticas (C #, ...).

são nomes de gatilho forçado a ser único no servidor SQL?

Como gatilhos são, por definição, aplicado a uma tabela específica não seria mais eficiente para restringir a pesquisa a apenas a tabela em questão?

Temos um banco de dados com mais de 30 mil mesas em que todos os que têm pelo menos um gatilho e pode ter mais (má concepção DB - muito provavelmente, mas fazia sentido anos atrás e não escala bem)

Eu uso

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

Gostaria de usar essa sintaxe para verificar e soltar gatilho

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]

Se você está tentando encontrar um servidor com escopo DDL gatilho no SQL Server 2014, você deve tentar sys.server_triggers.

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

Se eu dissesse tou nada incorreto, por favor me avise.

Edit: Eu não verificar para este dm em outro versões do SQL Server.

Gerado 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) 01 de junho de 2011 15:43:18 Copyright (c) Microsoft Corporation Enterprise Edition (64 bits) no Windows NT 6.1 (Construir 7601: Service Pack 1) (Hypervisor)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top