Подтвердить что ты не робот

Как добавить "ЕСЛИ НЕ СУЩЕСТВУЕТ" для создания оператора триггера

Я использую SQL Server 2008 R2. В частности, Microsoft SQL Server 2008 R2 (окончательная первоначальная версия) - 10.50.1600.1 (X64), 2 апреля 2010 г., 15:48:46 Авторское право (c) Microsoft Corporation Standard Edition (64-разрядная версия) в Windows NT 6.1 (сборка 7601: пакет обновления 1). ) (Гипервизор). Я новичок в SQL Server и процедуры/триггеры. У меня есть следующий код для создания триггера (он работает):

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

Как условно создать только если триггер еще не существует? Что я здесь не так делаю? У Qaru есть хорошие примеры IF NOT EXISTS, но я не могу заставить это работать вместе с CREATE. Вот одна из моих неудачных попыток:

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
4b9b3361

Ответ 1

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


 '

Ответ 2

Лучший способ - проверить объекты и отбросить их, если они существуют до их создания.

Вместо этого, не создавая его вообще, если он существует, я бы подошел к нему по-другому, отбрось его, если он существует, а затем создаст.

Обычно при длинных сценариях длины, если вы хотите обновить определение триггера, вы просто просто добавите это в конце этого script, и ваше определение триггера будет обновлено.

Таким образом, подход должен быть 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 .......

Ответ 3

Некоторые операторы, такие как 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;

Ответ 4

Поскольку в других ответах выше не упоминается важный момент, я написал такой ответ:

  • Когда мы хотим найти триггер или другой объект в таблице sys.objects, лучше точно проверить (с помощью схемы или object_id и т.д.) Предложение where, чтобы избежать неверных результатов с тем же именем. Рассмотрим, когда другой триггер с тем же именем уже существует в другой схеме... Поэтому, поскольку таблица sys.object содержит столбец schema_id, мы можем использовать его в дополнение к столбцам name и type для более точного запроса, как я указал в качестве примера ниже.

  • Как упоминалось в документах Microsoft здесь в разделе "Ограничения триггера":

CREATE TRIGGER должен быть первым оператором в пакете и может применяться только к одному столу.

поэтому мы используем 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

Ответ 5

Проверить IF Exist For Trigger

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 Exist для хранимой процедуры, функция также нажатием ссылки ниже http://www.gurujipoint.com/2017/05/check-if-exist-for-trigger-function-and.html