SQL Server에 트리거가 존재하는지 확인하는 가장 휴대용 방법은 무엇입니까?

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

문제

나는 찾고있다 가장 휴대용 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 서버 버전에서 작동하는지 확실하지 않습니다.

도움이 되었습니까?

해결책

이것은 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 (트리거입니다).

다른 팁

선호하는 "Sys.Triggers"카탈로그보기가 있습니다.

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

또는 sp_helptrigger 저장 Proc를 호출하십시오.

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

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 '타입'아래.

테스트 및 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')

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.

그런 다음 실행 된 결과가 줄을 반환했는지 여부를 확인하십시오. 이는 직접 SQL과 프로그래밍 방식 API (C#, ...)에서 쉽습니다.

트리거 이름이 SQL Server에서 고유해야합니까?

트리거가 정의에 따라 특정 테이블에 적용되므로 검색을 해당 테이블로만 제한하는 것이 더 효율적이지 않습니까?

우리는 30k가 넘는 테이블이있는 데이터베이스를 가지고 있으며,이 모든 것이 하나 이상의 트리거를 가지고 있고 더 많은 트리거를 가질 수 있습니다 (DB 디자인 - 아마도, 아마도 몇 년 전에는 잘 맞지 않았을 것입니다).

나는 사용한다

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

내가 잘못된 말을했다고 말하면 알려주세요.

편집 : 다른 버전의 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) 6 월 1 일 2011 15:43:18 저작권 (C) Windows NT 6.1의 Microsoft Corporation Enterprise Edition (64 -Bit) (빌드 7601 : 서비스 팩 1) (하이퍼바이저 )

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top