Триггер обновления T-SQL - PullRequest
0 голосов
/ 08 ноября 2018

Я пытаюсь создать следующий триггер в SQL Server, но SSMS выдает ошибку, и я понятия не имею, что это такое. Есть мысли?

Сообщение 156, Уровень 15, Состояние 1, Строка 2
Неверный синтаксис рядом с ключевым словом «триггер».

Код:

IF NOT EXISTS(SELECT * FROM sys.triggers 
              WHERE object_id = OBJECT_ID(N'[dbo].[trAfterUpdateInfoDoc]'))
    CREATE TRIGGER [dbo].[trAfterUpdateInfoDoc]
    ON [dbo].[InfoDocs]
    AFTER UPDATE
    AS
    BEGIN
        DECLARE @infodoctemplateid INT;
        DECLARE @infodocid INT;
        DECLARE @requireccount FLOAT(2);
        DECLARE @filledcount FLOAT(2);
        DECLARE @pcnt FLOAT(2);

        DECLARE c CURSOR FOR
             SELECT id 
             FROM InfoDocs ifd 
             WHERE exists (SELECT 1 FROM Inserted AS i WHERE i.id = ifd.id)

        OPEN c

        FETCH NEXT FROM c INTO @infodocid

        WHILE @@Fetch_Status = 0 
        BEGIN
            SELECT @infodoctemplateid = InfoDocTemplateId 
            FROM InfoDocs 
            WHERE id = @infodocid;

            SELECT @requireccount = COUNT(*) 
            FROM InfoDocTemplateFields 
            WHERE InfoDocTemplateId = @infodoctemplateid 
              AND IsRequired = 1;

            IF (@requireccount = 0)
            BEGIN
                set @pcnt = 100;
            END
            ELSE
            BEGIN
                select @filledcount = count(*) from InfoDocFields 
                where InfoDocId = @infodocid 
                and InfoDocTemplateFieldId in (select id from InfoDocTemplateFields where InfoDocTemplateId = @infodoctemplateid and IsRequired = 1)
                and (BooleanValue is not null or (StringValue is not null and StringValue <> '') or IntValue is not null or DateValue is not null)

                set @pcnt = @filledcount / @requireccount * 100.0;
            END
            update InfoDocs set PercentageCompleted = @pcnt Where id = @infodocid;

            Fetch next From c into @infodocid
        End
    Close c
    Deallocate c
END

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Каждый раз, когда создается объект SQL, такой как триггер, он должен быть единственным объектом, созданным в пакете. Пакет завершается ключевым словом GO.

Попробуйте изменить код, чтобы он соответствовал этой общей структуре, и посмотрите, работает ли он:

IF OBJECT_ID(N'[dbo].[trAfterUpdateInfoDoc]') IS NOT NULL
    DROP TRIGGER [dbo].[trAfterUpdateInfoDoc]
GO

CREATE TRIGGER [dbo].[trAfterUpdateInfoDoc]
ON [dbo].[InfoDocs]
AFTER UPDATE
AS
BEGIN
    --PLACE CODE HERE
END
GO
0 голосов
/ 08 ноября 2018

Создать триггер (раздел «Ограничения») должен быть первым оператором в пакете, поэтому вы не можете использовать проверку IF перед ним.

В SQL Server 2016 SP1 и более поздних версиях вы можете использовать CREATE OR ALTER TRIGGER ... для того же поведения.

Pre-SQL Server 2016 SP1, есть некоторые предложения здесь

Я также второй комментарий Зохара о том, что включение этой логики в триггер может вызвать у вас множество проблем с производительностью и, возможно, затруднить отслеживание неожиданного поведения / ошибок.

...