2009-09-11 2 views
15

Допустим, у меня есть триггер, как это:T-SQL: Правильный способ закрыть/DEALLOCATE курсор в триггере обновление

CREATE TRIGGER trigger1 
    ON [dbo].[table1] 
    AFTER UPDATE 
AS 
BEGIN    
    --declare some vars 
    DECLARE @Col1 SMALLINT 
    DECLARE @Col1 TINYINT 

    --declare cursor   
    DECLARE Cursor1 CURSOR FOR 
    SELECT Col1, Col2 FROM INSERTED    

    --do the job 
    OPEN Cursor1 
    FETCH NEXT FROM Cursor1 INTO @Col1, @Col2 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     IF ...something... 
     BEGIN   
      EXEC myProc1 @param1 = @Col1, @Param2 = @Col2 
     END    
     ELSE 
     IF ...something else... 
     BEGIN   
      EXEC myProc2 @param1 = @Col1, @Param2 = @Col2 
     END  

     FETCH NEXT FROM Cursor1 INTO @Col1, @Col2    
    END 

    --clean it up  
    CLOSE Cursor1 
    DEALLOCATE Cursor1     
END 

Я хочу быть уверен, что CURSOR1 всегда замкнут и освобождаться. Даже myProc1 или myProc2 терпят неудачу.

Должен ли я использовать блок try/catch?

+0

[Необходимое чтение] (http://www.sommarskog.se/error-handling-I.html). –

ответ

15

Да, используйте TRY/CATCH, но убедитесь, что вы освобождаете и т.д. после. К сожалению, в SQL Server нет окончательного решения.

Однако я предлагаю оборачивать это в другой Try/уловом

CREATE TRIGGER trigger1 ON [dbo].[table1] AFTER UPDATE 
AS 
BEGIN       
    --declare some vars 
    DECLARE @Col1 SMALLINT, @Col1 TINYINT 

    BEGIN TRY 
     --declare cursor    
     DECLARE Cursor1 CURSOR FOR 
     SELECT Col1, Col2 FROM INSERTED      

     --do the job 
     OPEN Cursor1 
     FETCH NEXT FROM Cursor1 INTO @Col1, @Col2 

     WHILE @@FETCH_STATUS = 0 
     BEGIN 
      IF ...something... 
        EXEC myProc1 @param1 = @Col1, @Param2 = @Col2 
      ELSE 
      IF ...something else... 
        EXEC myProc2 @param1 = @Col1, @Param2 = @Col2 

      FETCH NEXT FROM Cursor1 INTO @Col1, @Col2        
     END 
    END TRY 
    BEGIN CATCH 
     --do what you have to 
    END CATCH 

    BEGIN TRY 
     --clean it up    
     CLOSE Cursor1 
     DEALLOCATE Cursor1         
    END TRY 
    BEGIN CATCH 
     --do nothing 
    END CATCH 
END 

ли курсор в триггер является хорошей идеей, это совсем другое дело ...

+0

Что вы думаете об обертывании очистки курсора в блоке try/catch, когда catch не делает ничего? –

+4

@NickDeVore: потому что курсор уже может быть закрыт, в зависимости от того, как сбой proc1 или proc2 (в триггере, может быть, try/catch и т. Д.). Береженого Бог бережет. – gbn

+0

Можете ли вы использовать синтаксис TRY/CATCH в триггерах вообще? Я знаю, что при возникновении ошибки в триггере вся транзакция выходит из строя, есть ли try/catch или нет. – 2016-05-17 07:43:56

1

Что вы должны делать, никогда не используйте курсор в триггере. Вместо этого напишите правильный код на основе набора. Если бы кто-то импортировал данные в вашу таблицу из 100 000 новых записей, вы бы запирали таблицу в течение нескольких часов и приводили вашу базу к кричащей остановке. Очень плохо использовать курсор в триггере.

+1

Если кто-то импортировал данные в эту таблицу из 100 000 новых записей, он не закроет мою таблицу вообще (потому что это триггер после обновления;) Но серьезно. Не поймите меня неправильно. Я полностью понимаю, что вы имеете в виду, и вы правы. Я бы никогда не использовал курсор в триггере, если это не является абсолютно необходимым, и в моем случае это так. Теоретически только несколько строк могут обновляться одновременно с моим приложением (если кто-то не будет обновлять из Management Studio). Все работает отлично (и быстро), но мне интересно, что если один из моих SPs терпит неудачу. Должен ли я беспокоиться? – Novitzky

+0

Я бы предложил вам протестировать, внеся изменения в proc или вставить данные, которые гарантируют, что proc завершится с ошибкой. Тогда вы узнаете, что произойдет. – HLGEM

+0

Спасибо. Это именно то, что я собираюсь сделать. Как я уже говорил, я должен использовать курсор (иначе это было бы слишком много изменений в моем приложении), но я могу изменить свои SP. Спасибо, в любом случае. – Novitzky

Смежные вопросы