T-SQL Update Trigger











up vote
0
down vote

favorite












I'm trying to create the following trigger in SQL Server, but SSMS throws an error and I have no clue what it is. Any thoughts ?




Msg 156, Level 15, State 1, Line 2

Incorrect syntax near the keyword 'trigger'.




Code:



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









share|improve this question




















  • 2




    I don't know why you get a syntax error, but cursors should be only used as a last resort since they are performance killers, and in triggers they should be avoided almost at all costs. You should rewrite your trigger to work on a set based approach.
    – Zohar Peled
    Nov 8 at 17:59












  • Can you point me to an alternative for looping over a set and not using cursors
    – BrilBroeder
    Nov 8 at 18:33










  • Perhaps, but this is a different question - and should be on a different post. I know it seems petty and annoying at first, but when you think about it, the question You've asked was already answered by Martin Smith - so you should accept it and move on to the next question.
    – Zohar Peled
    Nov 8 at 18:41






  • 1




    create a new case as requested : stackoverflow.com/questions/53222867/…
    – BrilBroeder
    Nov 9 at 9:20















up vote
0
down vote

favorite












I'm trying to create the following trigger in SQL Server, but SSMS throws an error and I have no clue what it is. Any thoughts ?




Msg 156, Level 15, State 1, Line 2

Incorrect syntax near the keyword 'trigger'.




Code:



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









share|improve this question




















  • 2




    I don't know why you get a syntax error, but cursors should be only used as a last resort since they are performance killers, and in triggers they should be avoided almost at all costs. You should rewrite your trigger to work on a set based approach.
    – Zohar Peled
    Nov 8 at 17:59












  • Can you point me to an alternative for looping over a set and not using cursors
    – BrilBroeder
    Nov 8 at 18:33










  • Perhaps, but this is a different question - and should be on a different post. I know it seems petty and annoying at first, but when you think about it, the question You've asked was already answered by Martin Smith - so you should accept it and move on to the next question.
    – Zohar Peled
    Nov 8 at 18:41






  • 1




    create a new case as requested : stackoverflow.com/questions/53222867/…
    – BrilBroeder
    Nov 9 at 9:20













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I'm trying to create the following trigger in SQL Server, but SSMS throws an error and I have no clue what it is. Any thoughts ?




Msg 156, Level 15, State 1, Line 2

Incorrect syntax near the keyword 'trigger'.




Code:



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









share|improve this question















I'm trying to create the following trigger in SQL Server, but SSMS throws an error and I have no clue what it is. Any thoughts ?




Msg 156, Level 15, State 1, Line 2

Incorrect syntax near the keyword 'trigger'.




Code:



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






sql-server tsql triggers database-trigger






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 at 17:58









marc_s

565k12610921244




565k12610921244










asked Nov 8 at 17:52









BrilBroeder

364315




364315








  • 2




    I don't know why you get a syntax error, but cursors should be only used as a last resort since they are performance killers, and in triggers they should be avoided almost at all costs. You should rewrite your trigger to work on a set based approach.
    – Zohar Peled
    Nov 8 at 17:59












  • Can you point me to an alternative for looping over a set and not using cursors
    – BrilBroeder
    Nov 8 at 18:33










  • Perhaps, but this is a different question - and should be on a different post. I know it seems petty and annoying at first, but when you think about it, the question You've asked was already answered by Martin Smith - so you should accept it and move on to the next question.
    – Zohar Peled
    Nov 8 at 18:41






  • 1




    create a new case as requested : stackoverflow.com/questions/53222867/…
    – BrilBroeder
    Nov 9 at 9:20














  • 2




    I don't know why you get a syntax error, but cursors should be only used as a last resort since they are performance killers, and in triggers they should be avoided almost at all costs. You should rewrite your trigger to work on a set based approach.
    – Zohar Peled
    Nov 8 at 17:59












  • Can you point me to an alternative for looping over a set and not using cursors
    – BrilBroeder
    Nov 8 at 18:33










  • Perhaps, but this is a different question - and should be on a different post. I know it seems petty and annoying at first, but when you think about it, the question You've asked was already answered by Martin Smith - so you should accept it and move on to the next question.
    – Zohar Peled
    Nov 8 at 18:41






  • 1




    create a new case as requested : stackoverflow.com/questions/53222867/…
    – BrilBroeder
    Nov 9 at 9:20








2




2




I don't know why you get a syntax error, but cursors should be only used as a last resort since they are performance killers, and in triggers they should be avoided almost at all costs. You should rewrite your trigger to work on a set based approach.
– Zohar Peled
Nov 8 at 17:59






I don't know why you get a syntax error, but cursors should be only used as a last resort since they are performance killers, and in triggers they should be avoided almost at all costs. You should rewrite your trigger to work on a set based approach.
– Zohar Peled
Nov 8 at 17:59














Can you point me to an alternative for looping over a set and not using cursors
– BrilBroeder
Nov 8 at 18:33




Can you point me to an alternative for looping over a set and not using cursors
– BrilBroeder
Nov 8 at 18:33












Perhaps, but this is a different question - and should be on a different post. I know it seems petty and annoying at first, but when you think about it, the question You've asked was already answered by Martin Smith - so you should accept it and move on to the next question.
– Zohar Peled
Nov 8 at 18:41




Perhaps, but this is a different question - and should be on a different post. I know it seems petty and annoying at first, but when you think about it, the question You've asked was already answered by Martin Smith - so you should accept it and move on to the next question.
– Zohar Peled
Nov 8 at 18:41




1




1




create a new case as requested : stackoverflow.com/questions/53222867/…
– BrilBroeder
Nov 9 at 9:20




create a new case as requested : stackoverflow.com/questions/53222867/…
– BrilBroeder
Nov 9 at 9:20












2 Answers
2






active

oldest

votes

















up vote
3
down vote



accepted










Create Trigger (Limitations section) must be the first statement in a batch, so you can't use the IF exists check before it.



In SQL Server 2016 SP1 onwards, you can use CREATE OR ALTER TRIGGER... for the same behaviour.



Pre-SQL Server 2016 SP1, there's some suggestions here



I also second Zohar's comment that putting this logic into a trigger could well cause you many performance issues & possibly hard to track down unexpected behaviour/bugs.






share|improve this answer






























    up vote
    2
    down vote













    Anytime a SQL object like a trigger is created, it needs to be the only object created in the batch. A batch is terminated by the keyword GO.



    Try refactoring your code to fit this general structure and see if it works:



    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





    share|improve this answer





















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














       

      draft saved


      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53213489%2ft-sql-update-trigger%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      3
      down vote



      accepted










      Create Trigger (Limitations section) must be the first statement in a batch, so you can't use the IF exists check before it.



      In SQL Server 2016 SP1 onwards, you can use CREATE OR ALTER TRIGGER... for the same behaviour.



      Pre-SQL Server 2016 SP1, there's some suggestions here



      I also second Zohar's comment that putting this logic into a trigger could well cause you many performance issues & possibly hard to track down unexpected behaviour/bugs.






      share|improve this answer



























        up vote
        3
        down vote



        accepted










        Create Trigger (Limitations section) must be the first statement in a batch, so you can't use the IF exists check before it.



        In SQL Server 2016 SP1 onwards, you can use CREATE OR ALTER TRIGGER... for the same behaviour.



        Pre-SQL Server 2016 SP1, there's some suggestions here



        I also second Zohar's comment that putting this logic into a trigger could well cause you many performance issues & possibly hard to track down unexpected behaviour/bugs.






        share|improve this answer

























          up vote
          3
          down vote



          accepted







          up vote
          3
          down vote



          accepted






          Create Trigger (Limitations section) must be the first statement in a batch, so you can't use the IF exists check before it.



          In SQL Server 2016 SP1 onwards, you can use CREATE OR ALTER TRIGGER... for the same behaviour.



          Pre-SQL Server 2016 SP1, there's some suggestions here



          I also second Zohar's comment that putting this logic into a trigger could well cause you many performance issues & possibly hard to track down unexpected behaviour/bugs.






          share|improve this answer














          Create Trigger (Limitations section) must be the first statement in a batch, so you can't use the IF exists check before it.



          In SQL Server 2016 SP1 onwards, you can use CREATE OR ALTER TRIGGER... for the same behaviour.



          Pre-SQL Server 2016 SP1, there's some suggestions here



          I also second Zohar's comment that putting this logic into a trigger could well cause you many performance issues & possibly hard to track down unexpected behaviour/bugs.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 8 at 21:34









          marc_s

          565k12610921244




          565k12610921244










          answered Nov 8 at 18:02









          Gareth Lyons

          1,404413




          1,404413
























              up vote
              2
              down vote













              Anytime a SQL object like a trigger is created, it needs to be the only object created in the batch. A batch is terminated by the keyword GO.



              Try refactoring your code to fit this general structure and see if it works:



              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





              share|improve this answer

























                up vote
                2
                down vote













                Anytime a SQL object like a trigger is created, it needs to be the only object created in the batch. A batch is terminated by the keyword GO.



                Try refactoring your code to fit this general structure and see if it works:



                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





                share|improve this answer























                  up vote
                  2
                  down vote










                  up vote
                  2
                  down vote









                  Anytime a SQL object like a trigger is created, it needs to be the only object created in the batch. A batch is terminated by the keyword GO.



                  Try refactoring your code to fit this general structure and see if it works:



                  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





                  share|improve this answer












                  Anytime a SQL object like a trigger is created, it needs to be the only object created in the batch. A batch is terminated by the keyword GO.



                  Try refactoring your code to fit this general structure and see if it works:



                  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






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 8 at 18:24









                  mjcataldi

                  515




                  515






























                       

                      draft saved


                      draft discarded



















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53213489%2ft-sql-update-trigger%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Guess what letter conforming each word

                      Port of Spain

                      Run scheduled task as local user group (not BUILTIN)