web-dev-qa-db-ja.com

「IF NOT EXISTS」を追加してトリガーステートメントを作成する方法

SQL Server 2008 R2を使用しています。具体的には、Microsoft SQL Server 2008 R2(RTM)-10.50.1600.1(X64)2010年4月2日15:48:46 Copyright(c)Microsoft Corporation Standard Edition(64-bit)on Windows NT 6.1(Build 7601:Service Pack 1 )(ハイパーバイザー)。私はSQLサーバーとプロシージャ/トリガーを初めて使用します。トリガーを作成する次のコードがあります(動作します):

CREATE TRIGGER [dbo].[Insert_WithdrawalCodes] 
   ON  [dbo].[PupilWithdrawalReason] 
   AFTER INSERT
AS 
BEGIN
    SET NOCOUNT ON;
        UPDATE [dbo].[PupilWithdrawalReason] SET DateCreated=dbo.SYSTEMTIME() 
        WHERE WithdrawalCodeID IN (SELECT WithdrawalCodeID FROM inserted)
END

トリガーがまだ存在しない場合にのみ条件付きで作成するにはどうすればよいですか?ここで何が間違っていますか? Stackoverflowには「存在しない場合」の良い例がありますが、CREATEと連携して動作させることはできません。これが私の失敗した取り組みの1つです。

IF NOT EXISTS (SELECT * FROM sys.objects WHERE type = 'TR' AND name = 'Insert_WithdrawalCodes')
   exec('CREATE TRIGGER [dbo].[Insert_WithdrawalCodes] ON  [dbo].[PupilWithdrawalReason] AFTER INSERT AS BEGIN SET NOCOUNT ON; UPDATE [dbo].[PupilWithdrawalReason] SET DateCreated=dbo.SYSTEMTIME() WHERE WithdrawalCodeID IN (SELECT WithdrawalCodeID FROM inserted) END')
GO
33
IF EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[TRIGGERNAME]'))
DROP TRIGGER [dbo].[TRIGGERNAME]
go
IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[TABLENAME]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE   TRIGGER [dbo].[TRIGGERNAME] ON [dbo].[TABLENAME] FOR INSERT, UPDATE 

AS ...

END

更新された質問に基づいて...これを試してください:

IF NOT EXISTS (select * from sys.objects where type = 'TR' and name = 'Insert_WithdrawalCodes')
EXEC dbo.sp_executesql @statement = N'

CREATE TRIGGER [dbo].[Insert_WithdrawalCodes] 
   ON  [dbo].[PupilWithdrawalReason] 
   AFTER INSERT
AS 
BEGIN
    SET NOCOUNT ON;
        UPDATE [dbo].[PupilWithdrawalReason] SET DateCreated=dbo.SYSTEMTIME() 
        WHERE WithdrawalCodeID IN (SELECT WithdrawalCodeID FROM inserted)
END


 '
63
JStevens

最良の方法は、オブジェクトをチェックして、作成する前にオブジェクトが存在する場合はドロップすることです。

存在する場合はまったく作成せず、別の方法でアプローチし、存在する場合はドロップしてから作成します。

通常、長いスクリプトでは、トリガーの定義を更新する場合、そのスクリプトの最後にこれを追加するだけで、トリガー定義が更新されます。

したがって、アプローチはcreate the object but drop it if it already exists むしろその後 dont create it at all if it already exists

IF OBJECT_ID ('[Insert_WithdrawalCodes] ', 'TR') IS NOT NULL
   DROP TRIGGER [Insert_WithdrawalCodes];
GO

CREATE TRIGGER .......
12
M.Ali

CREATE TRIGGERなどの特定のステートメントは、バッチ内の最初のステートメントである必要があります(たとえば、GOで区切られたステートメントのグループ)。

https://msdn.Microsoft.com/en-us/library/ms175502.aspx

または、これを行うことができます

IF NOT EXISTS ( SELECT  *
            FROM    sys.objects
            WHERE   type = 'TR'
                    AND name = 'Insert_WithdrawalCodes' ) 
BEGIN
    EXEC ('CREATE TRIGGER Insert_WithdrawalCodes ON ...');
END;
7
Neel

上記の他の回答では重要な点に言及していなかったため、私はこの回答を書きました。

  • sys.objectsテーブルでトリガーまたは別のオブジェクトを検索する場合は、同じ名前の無効な結果を避けるために、where句で(スキーマまたはobject_idなどを使用して)正確に確認することをお勧めします。同じ名前の別のトリガーが別のスキーマに既に存在する場合を検討してください。したがって、sys.objectテーブルにはschema_id列が含まれているため、nameおよびtype列は、以下の例のように、より正確にクエリを実行します。

  • Microsoftのドキュメントで述べたように、 こちら 「トリガーの制限」の下:

CREATE TRIGGERはバッチの最初のステートメントである必要があり、1つのテーブルにのみ適用できます。

したがって、この制限を克服するために [〜#〜] execute [〜#〜] を使用します。

IF NOT EXISTS (select * from sys.objects where schema_id=SCHEMA_ID('dbo') AND type='TR' and name='Insert_WithdrawalCodes')
BEGIN
   EXECUTE ('CREATE TRIGGER [Insert_WithdrawalCodes] ON [dbo].[PupilWithdrawalReason]
   AFTER INSERT
   AS 
   BEGIN
      SET NOCOUNT ON;
      ...
   END');
END
2
lifestyle

トリガーの存在を確認する

IF EXISTS (SELECT * FROM sys.objects WHERE [name] = 
                 N'[Trigger_Name]' AND [type] = 'TR')
 BEGIN
 DROP TRIGGER [Trigger_Name]
 Print('Trigger dropped => [Schema].[Trigger_Name]')
 END
 GO

ストアドプロシージャのIFが存在するかどうかを確認するには、以下のリンクをクリックしてください http://www.gurujipoint.com/2017/05/check-if-exist-for-trigger-function-and.html

0
Jatin Phulera