Ich verwende SQL Server 2008 R2. Genauer gesagt, Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) 2. April 2010 15:48:46 Copyright (c) Microsoft Corporation Standard Edition (64-Bit) unter Windows NT 6.1 (Build 7601: Service Pack 1) ) (Hypervisor). Ich bin neu in SQL Server und Prozeduren/Triggern. Ich habe den folgenden Code zum Erstellen eines Auslösers (es funktioniert):
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
Wie erstelle ich bedingt, wenn der Auslöser noch nicht existiert? Was mache ich hier falsch? Stackoverflow hat gute Beispiele für "Wenn nicht vorhanden", aber ich kann nicht, dass dies in Verbindung mit einem CREATE funktioniert. Hier ist eine meiner gescheiterten Bemühungen:
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
Basierend auf Ihrer aktualisierten Frage ... versuchen Sie Folgendes:
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
'
Am besten prüfen Sie, ob Objekte vorhanden sind, und legen Sie sie ab, wenn sie vorhanden sind, bevor Sie sie erstellen.
Anstatt es überhaupt zu erstellen, wenn es existiert, würde ich es andersherum angehen, es fallen lassen, wenn es existiert, und dann erstellen.
Normalerweise müssen Sie in langen Skripts, wenn Sie die Definition eines Auslösers aktualisieren möchten, diese einfach am Ende dieses Skripts hinzufügen und Ihre Auslöserdefinition wird aktualisiert.
Der Ansatz sollte also create the object but drop it if it already exists
sein und nicht 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 .......
Bestimmte Anweisungen wie CREATE TRIGGER müssen die ersten in einem Stapel sein (wie in durch GO getrennte Gruppe von Anweisungen).
https://msdn.Microsoft.com/de-de/library/ms175502.aspx
Alternativ können Sie das auch tun
IF NOT EXISTS ( SELECT *
FROM sys.objects
WHERE type = 'TR'
AND name = 'Insert_WithdrawalCodes' )
BEGIN
EXEC ('CREATE TRIGGER Insert_WithdrawalCodes ON ...');
END;
Da andere Antworten oben keinen wichtigen Punkt erwähnten, schrieb ich diese Antwort:
Wenn wir einen Trigger oder ein anderes Objekt in der Tabelle sys.objects
Suchen möchten, ist es besser, die where-Klausel (mit Schema oder object_id
Usw.) genau zu überprüfen, um ungültige Ergebnisse mit demselben Namen zu vermeiden. Überlegen Sie, wann ein anderer Trigger mit demselben Namen bereits in einem anderen Schema vorhanden ist. Da die Tabelle sys.object
Eine Spalte schema_id
Enthält, können wir sie daher zusätzlich zu name
verwenden. und type
Spalten, um eine genauere Abfrage durchzuführen, wie ich unten als Beispiel angegeben habe.
Wie in den Microsoft-Dokumenten hier unter "Auslöserbeschränkungen" erwähnt:
CREATE TRIGGER muss die erste Anweisung im Stapel sein und kann nur für eine Tabelle gelten.
deshalb verwenden wir EXECUTE , um diese Einschränkung zu überwinden:
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
Prüfen Sie, ob der Trigger vorhanden ist
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
Prüfen Sie, ob es sich um gespeicherte Prozedur handelt, Funktion auch durch Klicken auf den folgenden Link http://www.gurujipoint.com/2017/05/check-if-exist-for-trigger-function-and.html