Click here to monitor SSC
SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
 
 
 
        
Home       Members    Calendar    Who's On


Add to briefcase ««1234»»»

Introduction to DML Triggers Expand / Collapse
Author
Message
Posted Tuesday, October 14, 2008 8:15 AM


SSChampion

SSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampion

Group: General Forum Members
Last Login: Today @ 12:38 PM
Points: 11,314, Visits: 13,101
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

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
Post #585500
Posted Tuesday, October 14, 2008 10:28 AM
SSC Veteran

SSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC Veteran

Group: General Forum Members
Last Login: 2 days ago @ 3:43 PM
Points: 266, Visits: 2,593
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
Post #585620
Posted Tuesday, October 14, 2008 12:12 PM


Right there with Babe

Right there with BabeRight there with BabeRight there with BabeRight there with BabeRight there with BabeRight there with BabeRight there with BabeRight there with Babe

Group: General Forum Members
Last Login: Friday, April 4, 2014 4:40 PM
Points: 751, Visits: 917
Very well written article.

---
Timothy A Wiseman
SQL Blog: http://timothyawiseman.wordpress.com/
Post #585704
Posted Tuesday, October 14, 2008 12:40 PM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy Eights

Group: General Forum Members
Last Login: Thursday, June 5, 2014 10:54 AM
Points: 9,902, Visits: 9,480
Awesome article Jack!

-- RBarryYoung, (302)375-0451 blog: MovingSQL.com, Twitter: @RBarryYoung
Proactive Performance Solutions, Inc.
"Performance is our middle name."
Post #585719
Posted Tuesday, October 14, 2008 1:04 PM


SSChampion

SSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampion

Group: General Forum Members
Last Login: Today @ 12:38 PM
Points: 11,314, Visits: 13,101
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

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
Post #585731
Posted Tuesday, October 14, 2008 3:31 PM
SSC Rookie

SSC RookieSSC RookieSSC RookieSSC RookieSSC RookieSSC RookieSSC RookieSSC Rookie

Group: General Forum Members
Last Login: Tuesday, September 6, 2011 10:08 AM
Points: 44, 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.
Post #585842
Posted Tuesday, October 14, 2008 3:59 PM


SSChampion

SSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampion

Group: General Forum Members
Last Login: Today @ 12:38 PM
Points: 11,314, Visits: 13,101
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

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
Post #585853
Posted Tuesday, October 14, 2008 4:41 PM
Ten Centuries

Ten CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen Centuries

Group: General Forum Members
Last Login: Thursday, September 11, 2014 2:28 PM
Points: 1,218, Visits: 890
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.
Post #585870
Posted Tuesday, October 14, 2008 5:30 PM


SSChampion

SSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampion

Group: General Forum Members
Last Login: Today @ 12:38 PM
Points: 11,314, Visits: 13,101
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

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
Post #585876
Posted Tuesday, October 14, 2008 5:44 PM
Old Hand

Old HandOld HandOld HandOld HandOld HandOld HandOld HandOld Hand

Group: General Forum Members
Last Login: Thursday, June 12, 2014 1:08 AM
Points: 385, Visits: 344
Robert,

You can stop an update from occurring by issuing a rollback within the trigger.
Post #585880
« Prev Topic | Next Topic »

Add to briefcase ««1234»»»

Permissions Expand / Collapse