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
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
'
最良の方法は、オブジェクトをチェックして、作成する前にオブジェクトが存在する場合はドロップすることです。
存在する場合はまったく作成せず、別の方法でアプローチし、存在する場合はドロップしてから作成します。
通常、長いスクリプトでは、トリガーの定義を更新する場合、そのスクリプトの最後にこれを追加するだけで、トリガー定義が更新されます。
したがって、アプローチは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 .......
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;
上記の他の回答では重要な点に言及していなかったため、私はこの回答を書きました。
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
トリガーの存在を確認する
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