web-dev-qa-db-ja.com

トリガーが存在する場合はドロップして作成

[tbl]にトリガーが存在するかどうかを確認し、別のトリガーを作成したいと思います。この方法で試しましたが、うまくいきませんでした。何が間違っていますか?

IF EXISTS (SELECT * FROM sys.objects WHERE [name] = '[dbo].[trg]' AND [type] = 'TR')
      DROP TRIGGER [dbo].[trg] ON [dbo].[tbl]
GO
CREATE TRIGGER [dbo].[trg] ON [dbo].[tbl] 
AFTER DELETE
AS
BEGIN
   //
END
GO
18
user3399326

[name]sys.objectsフィールドには、実際の名前(つまり、trg)、notスキーマ(この場合はdbo)またはテキスト修飾子(この場合は[および])のみが含まれます。

また、トリガーはそれ自体がオブジェクトであるため(インデックスとは異なり)、DROP TRIGGERのテーブル名を指定しません。したがって、ON句を削除する必要があります(これはDDLおよびLogonトリガーでのみ使用されます)。

IF EXISTS (SELECT * FROM sys.objects WHERE [name] = N'trg' AND [type] = 'TR')
BEGIN
      DROP TRIGGER [dbo].[trg];
END;

[name]フィールドはNVARCHAR(128)と等しいNデータ型であるため、オブジェクト名文字列リテラルの前にsysnameを付ける必要があることに注意してください。

スキーマ名を組み込みたい場合は、スキーマ名とテキスト修飾子を許可するOBJECT_ID()関数を使用できます(nameではなく、object_idと照合する必要があります)。

IF EXISTS (SELECT * FROM sys.objects WHERE [object_id] = OBJECT_ID(N'[dbo].[trg]')
               AND [type] = 'TR')
BEGIN
      DROP TRIGGER [dbo].[trg];
END;

オブジェクト名はスキーマ内で一意である必要があるため、単純化するには、実際にその存在をテストするだけです。何らかの理由でその名前の別のオブジェクトタイプが存在する場合、他のオブジェクトはトリガーではないため、DROP TRIGGERは失敗します;-)。したがって、私は次を使用します:

IF (OBJECT_ID(N'[dbo].[trg]') IS NOT NULL)
BEGIN
      DROP TRIGGER [dbo].[trg];
END;
38
Solomon Rutzky

SQL Server 2016を使用している場合、より短いバリアントを使用できます。

DROP TRIGGER IF EXISTS [dbo].[trg]

https://docs.Microsoft.com/en-us/sql/t-sql/statements/drop-trigger-transact-sql

4
Neshta

試せますか

SELECT * FROM sys.objects WHERE [name] = PARSENAME('[dbo].[trg]',1) AND [type] = 'TR'

編集:

よくsrutzkyはあなたに答えを与え、十分に説明しました、 [〜#〜] parsename [〜#〜] の助けを借りて名前を解析できます。

0
mxix