web-dev-qa-db-de.com

Wie füge ich "IF NOT EXISTS" hinzu, um eine Trigger-Anweisung zu erstellen?

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
27
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


 '
60
JStevens

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 .......
12
M.Ali

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;
7
Neel

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
2
lifestyle

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

0
Jatin Phulera