49

MSSQLServerにトリガーが存在するかどうかを確認するための最も移植性の高い方法を探しています。少なくともSQLServer2000、2005、できれば2008で動作する必要があります。

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

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

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

end

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

4

9 に答える 9

63

推奨される「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
于 2009-03-11T21:33:46.980 に答える
34

これは、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返しNULLNULL(もちろん) 存在しない<> 1(またはその他のもの) ためです。

SQL Server 2005 以降では、これCOALESCEに対処するために使用できますが、SQL Server 2000 をサポートする必要がある場合は、次の 3 つの戻り値を処理するようにステートメントを構成する必要がありますNULL。 all)、0(存在するがトリガーではない)、または1(トリガーである)。

于 2010-08-05T14:40:19.213 に答える
9

それが 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の「タイプ」を参照してください。

于 2011-11-12T23:27:35.827 に答える
2

テスト済みで、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')
于 2009-04-09T09:03:43.073 に答える
2

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 を確認しませんでした。

于 2014-07-16T17:31:20.497 に答える
2

marc_sによる優れた回答に加えて:

何らかの方法でトリガーを削除または変更する前に存在チェックtry/Catchが意図されている場合は、最速の手段として直接 TSQL ブロックを使用します。

例えば:

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#など)で簡単です。

于 2013-12-08T12:29:53.960 に答える
1

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

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

データベースには 30,000 を超えるテーブルがあり、そのすべてに少なくとも 1 つのトリガーがあり、さらに多くのトリガーがある可能性があります (不適切な DB 設計 - かなりの可能性がありますが、何年も前に意味があり、うまくスケーリングしませんでした)

私が使う

SELECT * FROM sys.triggers 
WHERE [parent_id] = OBJECT_ID(@tableName) 
AND [name] = @triggerName
于 2013-02-04T10:58:04.573 に答える
1

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

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]
于 2014-01-15T08:09:41.460 に答える