2015-01-29 15 views
20

Używam serwera sql 2008 R2. Dokładniej: Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) 2 kwietnia 2010 15:48:46 Prawa autorskie (c) Microsoft Corporation Standard Edition (64-bit) w systemie Windows NT 6.1 (Kompilacja 7601: Service Pack 1) (Hypervisor). Jestem nowy w serwerze sql i procedurach/wyzwalaczach. Mam następujący kod do utworzenia wyzwalacza (działa):Jak dodać "JEŚLI NIE ISTNIEJ" do utworzenia instrukcji wyzwalacza

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 

Jak warunkowo utworzyć tylko wtedy, gdy wyzwalacz jeszcze nie istnieje? Co ja tu robię źle? Stackoverflow ma dobre przykłady "jeśli nie istnieje", ale nie mogę tego zrobić w połączeniu z CREATE. Oto jeden z moich nieudanych wysiłków:

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 
+0

Zaktualizowałem mój fa Podany przykład. Dlaczego nie działa kod "exec"? Czy moja składnia jest błędna w utworze? – thebiggestlebowski

Odpowiedz

47
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 

podstawie zaktualizowanego pytanie ... spróbuj tego:

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 


' 
+0

Naprawdę chcę użyć "jeśli nie istnieje". To pytanie zawiera kilka odpowiedzi wyjaśniających, dlaczego "jeśli nie istnieje" jest lepsze. http://stackoverflow.com/questions/937908/how-to-detect-if-a-stored-procedure-already-exists. – thebiggestlebowski

+1

Zmieniłem moją odpowiedź, aby odzwierciedlić zmiany w pytaniu ... – JStevens

+0

Dziękuję za twoje wysiłki. Próbowałem tego kodu i otrzymałem to: Błąd SQL03070: Ta instrukcja nie jest rozpoznawana w tym kontekście. – thebiggestlebowski

9

Najlepszym sposobem jest sprawdzenie obiektów i upuść jeśli one istnieją, zanim je stworzyć.

Zamiast tworzyć go w ogóle, jeśli istnieje, podchodzę do niego w inny sposób, upuszczam go, jeśli istnieje, a następnie tworzy.

Zwykle w długich skryptach, jeśli chcesz zaktualizować definicję wyzwalacza, wystarczy dodać to na końcu tego skryptu, a definicja wyzwalacza zostanie zaktualizowana.

więc podejście powinno być create the object but drop it if it already exists a następnie 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 ....... 
+0

Naprawdę chcę użyć "jeśli nie istnieje". To pytanie zawiera kilka odpowiedzi wyjaśniających, dlaczego "jeśli nie istnieje" jest lepsze. http://stackoverflow.com/questions/937908/how-to-detect-if-a-stored-procedure-already-exists. – thebiggestlebowski

+0

Dla tych, którzy szukają wyjaśnienia: 'jeśli nie istnieje' pozwala na sprawdzenie, czy obiekt rzeczywiście jest wyzwalaczem. –

4

Pewne oświadczenia podoba TWORZENIE TRIGGER musi być pierwszy w grupie (jak w grupie oświadczeń oddzielonych GO).

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

Ewentualnie można zrobić

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

Próbowałem tego, ale to nie zadziałało. Zamierzam zaktualizować moje pytanie za pomocą kodu, który nie zadziałał - byłby świetny, jeśli zauważysz, dlaczego nie działa. http://stackoverflow.com/questions/937908/how-to-detect-if-a-stored-procedure-already-exists. – thebiggestlebowski

+0

Brakuje średnika po EXEC(). Wypróbuj EXEC (WCIĄŻ TRYB. [Dbo]. [Wstaw kody wypłaty] WŁ [dbo]. [PupilOdwzględnij Reason] PO WSTAWIE JAKO ZACZYNAJ USTAW NOCOUNT WŁ., AKTUALIZACJA [dbo]. [PupilWithdrawalReason] SET DateCreated = dbo.SYSTEMTIME() WHERE WithdrawalCodeID IN (WYBIERZ Wstawiono ID wyprowadzenia FROM) END "); – Neel

+0

Dziękuję za uwagę! – thebiggestlebowski

0

sprawdzić, czy istnieją dla wyzwalacza

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 

sprawdzić, czy istnieją dla procedury przechowywanej, funkcjonują również klikając odnośnik poniżej http://www.gurujipoint.com/2017/05/check-if-exist-for-trigger-function-and.html