web-dev-qa-db-ja.com

SQL Serverにトリガーが存在するかどうかを確認する最もポータブルな方法は何ですか?

MS SQL Serverのトリガーの存在を確認するmost portableメソッドを探しています。少なくともSQL Server 2000、2005、できれば2008で動作する必要があります。

情報はINFORMATION_SCHEMAにあるようには見えませんが、どこかにある場合は、そこから使用したいと思います。

私はこの方法を知っています:

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

end

しかし、すべてのバージョンのSQL Serverで機能するかどうかはわかりません。

48
Blorgbeard

これは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

...オブジェクトがまったく存在しない場合、OBJECTPROPERTYNULLを返し、NULLは(もちろん)<> 1(またはその他)ではありません。

SQL Server 2005以降では、COALESCEを使用してそれを処理できますが、SQL Server 2000をサポートする必要がある場合は、3つの可能な戻り値を処理するようにステートメントを構造化する必要があります:NULL(オブジェクトがまったく存在しない)、0(存在するがトリガーではない)、または1(トリガーである)。

34
wqw

優先される「sys.triggers」カタログビューもあります。

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

または、sp_Helptriggerストアドプロシージャを呼び出します。

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
60
marc_s

それが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 under 'type' 。

9
BodzioM

Marc_sによる優れた答えに加えて:

何らかの方法でトリガーをドロップまたは変更する前にexistence checkが意図されている場合は、直接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#、...)で簡単に実行できます。

2
Lorenz Lo Sauer

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')
2
EJM

トリガー名はSQLサーバーで一意にする必要がありますか?

トリガーは定義により特定のテーブルに適用されるため、問題のテーブルのみに検索を制限するのは効率的ではないでしょうか?

データベースには3万個以上のテーブルがあり、それらのすべてに少なくとも1つのトリガーがあり、さらにトリガーがある場合があります(DBの設計が悪い-おそらく、数年前に意味があり、うまくスケールしませんでした)

私が使う

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

この構文を使用して、トリガーをチェックしてドロップします

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]
1
Arvind Sedha

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

間違ったことをtouに伝えた場合は、お知らせください。

編集:SQL Serverの別のバージョンでこのdmを確認しませんでした。

1
Diego Grigol

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)2011年6月1日15:43:18著作権(c)Windows NT 6.1(ビルド7601:Service Pack 1)上のMicrosoft Corporation Enterprise Edition(64ビット)(ハイパーバイザー)

0
Kiquenet