SQL Clone
SQLServerCentral is supported by Redgate
 
Log in  ::  Register  ::  Not logged in
 
 
 


Introduction to DML Triggers


Introduction to DML Triggers

Author
Message
Jack Corbett
  Jack Corbett
SSC-Insane
SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)

Group: General Forum Members
Points: 24678 Visits: 14905
Andy Lennon (10/14/2008)
I had a faulty trigger implementation a while back that I couldn't figure out. You're article let me see the problem.

Thanks Jack


Awesome. That's why I write so it's rewarding to hear it helped someone.



Jack Corbett

Applications Developer

Don't let the good be the enemy of the best. -- Paul Fleming
At best you can say that one job may be more secure than another, but total job security is an illusion. -- Rod at work

Check out these links on how to get faster and more accurate answers:
Forum Etiquette: How to post data/code on a forum to get the best help
Need an Answer? Actually, No ... You Need a Question
How to Post Performance Problems
Crosstabs and Pivots or How to turn rows into columns Part 1
Crosstabs and Pivots or How to turn rows into columns Part 2
JJ B
JJ B
Say Hey Kid
Say Hey Kid (689 reputation)Say Hey Kid (689 reputation)Say Hey Kid (689 reputation)Say Hey Kid (689 reputation)Say Hey Kid (689 reputation)Say Hey Kid (689 reputation)Say Hey Kid (689 reputation)Say Hey Kid (689 reputation)

Group: General Forum Members
Points: 689 Visits: 2860
There's one part of this article that I particularly appreciated. I had often read about certain tasks not not belonging in a trigger. But I could not figure out how one could automate and ensure the action happened if it wasn't coded at the database level. Now I know the idea of setting up the staging table in the trigger and later scheduling a job to do tasks off of the staging table. I rarely use triggers and when I do, it is usually just for basic auditing or occasional data validation stuff. So, I don't have an immediate use for this idea. But I will remember the idea and appreciate you writing about it.
Thanks, - JJ
timothyawiseman
timothyawiseman
UDP Broadcaster
UDP Broadcaster (1.5K reputation)UDP Broadcaster (1.5K reputation)UDP Broadcaster (1.5K reputation)UDP Broadcaster (1.5K reputation)UDP Broadcaster (1.5K reputation)UDP Broadcaster (1.5K reputation)UDP Broadcaster (1.5K reputation)UDP Broadcaster (1.5K reputation)

Group: General Forum Members
Points: 1478 Visits: 920
Very well written article.

---
Timothy A Wiseman
SQL Blog: http://timothyawiseman.wordpress.com/
RBarryYoung
RBarryYoung
SSCoach
SSCoach (19K reputation)SSCoach (19K reputation)SSCoach (19K reputation)SSCoach (19K reputation)SSCoach (19K reputation)SSCoach (19K reputation)SSCoach (19K reputation)SSCoach (19K reputation)

Group: General Forum Members
Points: 19672 Visits: 9518
Awesome article Jack!

-- RBarryYoung, (302)375-0451 blog: MovingSQL.com, Twitter: @RBarryYoung
Proactive Performance Solutions, Inc.
"Performance is our middle name."
Jack Corbett
  Jack Corbett
SSC-Insane
SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)

Group: General Forum Members
Points: 24678 Visits: 14905
JJ, Timothy, and Barry,

Thanks for the kind words. I just hope the article can be helpful especially to beginners.



Jack Corbett

Applications Developer

Don't let the good be the enemy of the best. -- Paul Fleming
At best you can say that one job may be more secure than another, but total job security is an illusion. -- Rod at work

Check out these links on how to get faster and more accurate answers:
Forum Etiquette: How to post data/code on a forum to get the best help
Need an Answer? Actually, No ... You Need a Question
How to Post Performance Problems
Crosstabs and Pivots or How to turn rows into columns Part 1
Crosstabs and Pivots or How to turn rows into columns Part 2
Erik-131897
Erik-131897
SSC Journeyman
SSC Journeyman (86 reputation)SSC Journeyman (86 reputation)SSC Journeyman (86 reputation)SSC Journeyman (86 reputation)SSC Journeyman (86 reputation)SSC Journeyman (86 reputation)SSC Journeyman (86 reputation)SSC Journeyman (86 reputation)

Group: General Forum Members
Points: 86 Visits: 558
Nice article. So what's considered excessive trigger use? We have some triggers that are 2000 lines and do a whole lot of data cleanup. They fire recursively too and we've occasionally hit that 32 level limit.
Jack Corbett
  Jack Corbett
SSC-Insane
SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)

Group: General Forum Members
Points: 24678 Visits: 14905
I don't know that I'd call a trigger excessive because of the number of lines of code, but more by what it does and how long it takes. I would consider a trigger that recurses to be a candidate for evaluation. It sounds like the processing you are doing needs to be moved out of the trigger though.

If the triggers are part of an ETL process I'd look into SSIS or another way to process the data.



Jack Corbett

Applications Developer

Don't let the good be the enemy of the best. -- Paul Fleming
At best you can say that one job may be more secure than another, but total job security is an illusion. -- Rod at work

Check out these links on how to get faster and more accurate answers:
Forum Etiquette: How to post data/code on a forum to get the best help
Need an Answer? Actually, No ... You Need a Question
How to Post Performance Problems
Crosstabs and Pivots or How to turn rows into columns Part 1
Crosstabs and Pivots or How to turn rows into columns Part 2
Robert-378556
Robert-378556
SSCommitted
SSCommitted (1.9K reputation)SSCommitted (1.9K reputation)SSCommitted (1.9K reputation)SSCommitted (1.9K reputation)SSCommitted (1.9K reputation)SSCommitted (1.9K reputation)SSCommitted (1.9K reputation)SSCommitted (1.9K reputation)

Group: General Forum Members
Points: 1938 Visits: 1010
Jack Corbett (10/14/2008)


Robert,

Thanks for the comment. I believe you are incorrect in stating that the transaction will not fail on an error with the trigger. An error in a trigger will cause a rollback in my experience. Your are correct in stating that the client application should handle it, and then you can re-submit a corrected transaction, but left to itself the data modification is rolled back either explicitly like in your code, or implicitly.

You're right with your test case, but that's the side effect of try..catch. The client gets the result of a select in catch block, but no error.
Try this:

create table dbo.testXa
( a integer)
go
create trigger [dbo].[ti_test] on [dbo].[testXa] after insert
as raiserror 19999 'Sorry, not insertable'
go
select * from testxa
--emtpy table
insert into testxa values (123)
--we got an error
select * from testxa
--insert took place anyway
begin try
insert into testxa values (124)
end try
begin catch
SELECT 'Error in Trigger' AS error, Error_Message() AS MESSAGE
end catch
go
select * from testxa
--no insert took place
drop table dbo.testXa



The first insert is not rolled back. You usually use try..catch in triggers and stored procs when necessary, but client application generated update statements are usually plain update statements without try...catch.

I asked some time ago how to prevent such updates. One of options is INSTEAD OF trigger, which is not as handy as BEFORE trigger on other servers, but serves the purpose.
Jack Corbett
  Jack Corbett
SSC-Insane
SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)SSC-Insane (24K reputation)

Group: General Forum Members
Points: 24678 Visits: 14905
Robert,

Using RaisError the way you use it in your example is generating an error message for the client, but is not actually an error in the trigger which is why the transaction is completing. As far as SQL Server is concerned the error has been handled and the trigger returns 0 for success. To demonstrate try this code:


CREATE PROCEDURE dbo.test
AS

--select 'test'
RAISERROR 19999 'test';


GO
DECLARE @retval INT

EXEC
@retval = dbo.test

SELECT @retval

DROP PROCEDURE dbo.test





For a trigger with an actual error the transaction is rolled back. In the following code I am trying to insert a value too large for the data type so the outer transaction fails in both cases:


CREATE TABLE dbo.testXa
    
(
    
a integer
    
)

CREATE TABLE dbo.TestXb
    
(
    
b tinyint
    
)
GO

CREATE TRIGGER [dbo].[ti_test] ON [dbo].[testXa]

after
INSERT

AS

INSERT INTO
dbo.TestXb
    
SELECT
        
*
    
FROM
        
inserted
  
GO

SELECT
    
*
FROM
    
testxa

--emtpy table
INSERT INTO testxa
    
VALUES
        
(
        
1234
        
)

--we got an error, not raised an error so no insert
SELECT
        
*
FROM
    
testxa

SELECT
    
*
FROM
    
testxb

GO

BEGIN try
    
INSERT INTO testxa
        
VALUES
        
(
        
12345
        
)
END try
BEGIN catch
    
SELECT
          
'Error in Trigger' AS error,
            
Error_Message() AS MESSAGE
END
catch
GO

--no insert took place
SELECT
    
*
FROM
    
testxa

DROP TABLE dbo.testXa
DROP TABLE dbo.testXb




Even if I use Try-Catch in the trigger I get a rollback:

CREATE TRIGGER [dbo].[ti_test] ON [dbo].[testXa] 

after
INSERT

AS

    BEGIN
try
        
--will not work due to overflow
        
INSERT INTO dbo.TestXB
            
SELECT
                
*
            
FROM
                
inserted

  
END Try
  
BEGIN Catch
        
DECLARE @error VARCHAR(500)
        
SET @error = Error_Message()
        
SELECT @error
        
  
END Catch






Jack Corbett

Applications Developer

Don't let the good be the enemy of the best. -- Paul Fleming
At best you can say that one job may be more secure than another, but total job security is an illusion. -- Rod at work

Check out these links on how to get faster and more accurate answers:
Forum Etiquette: How to post data/code on a forum to get the best help
Need an Answer? Actually, No ... You Need a Question
How to Post Performance Problems
Crosstabs and Pivots or How to turn rows into columns Part 1
Crosstabs and Pivots or How to turn rows into columns Part 2
John te Lintelo
John te Lintelo
SSC-Addicted
SSC-Addicted (414 reputation)SSC-Addicted (414 reputation)SSC-Addicted (414 reputation)SSC-Addicted (414 reputation)SSC-Addicted (414 reputation)SSC-Addicted (414 reputation)SSC-Addicted (414 reputation)SSC-Addicted (414 reputation)

Group: General Forum Members
Points: 414 Visits: 388
Robert,

You can stop an update from occurring by issuing a rollback within the trigger.
Go


Permissions

You can't post new topics.
You can't post topic replies.
You can't post new polls.
You can't post replies to polls.
You can't edit your own topics.
You can't delete your own topics.
You can't edit other topics.
You can't delete other topics.
You can't edit your own posts.
You can't edit other posts.
You can't delete your own posts.
You can't delete other posts.
You can't post events.
You can't edit your own events.
You can't edit other events.
You can't delete your own events.
You can't delete other events.
You can't send private messages.
You can't send emails.
You can read topics.
You can't vote in polls.
You can't upload attachments.
You can download attachments.
You can't post HTML code.
You can't edit HTML code.
You can't post IFCode.
You can't post JavaScript.
You can post emoticons.
You can't post or upload images.

Select a forum

































































































































































SQLServerCentral


Search