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で機能するかどうかはわかりません。
これは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をサポートする必要がある場合は、3つの可能な戻り値を処理するようにステートメントを構造化する必要があります:NULL
(オブジェクトがまったく存在しない)、0
(存在するがトリガーではない)、または1
(トリガーである)。
優先される「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
それが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' 。
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#、...)で簡単に実行できます。
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')
トリガー名はSQLサーバーで一意にする必要がありますか?
トリガーは定義により特定のテーブルに適用されるため、問題のテーブルのみに検索を制限するのは効率的ではないでしょうか?
データベースには3万個以上のテーブルがあり、それらのすべてに少なくとも1つのトリガーがあり、さらにトリガーがある場合があります(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
間違ったことをtouに伝えた場合は、お知らせください。
編集: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)2011年6月1日15:43:18著作権(c)Windows NT 6.1(ビルド7601:Service Pack 1)上のMicrosoft Corporation Enterprise Edition(64ビット)(ハイパーバイザー)