PostgreSQL Help
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsDatabasesPostgreSQL Help
Receive the tools necessary to be the rock star of your field. Our 12-month program teaches you the evolving world of multi-channel marketing as well as the complex issues and opportunities found in the industry.

ASP Free and Iron Speed Designer are giving away $5,500+ in FREE licenses. Iron Speed's RAD CASE toolset can save up to 80% of your coding time. One free license per week, one perpetual license per month!
Download and Activate to enter!

Web development can be a daunting task, even for specialists. There is a lot of information to absorb and a lot of technologies to learn in order to manage a superior website. When trying to learn the ropes, developers need a reliable source to introduce new ideas that can be easily implemented. When working on large projects, even web veterans may run into a technology or an aspect of a technology that they are unfamiliar with.

Learn More!


Download to Enter
| Contest Rules

Tutorials | Forums

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old January 8th, 2012, 10:37 PM
freshquiz freshquiz is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2012
Posts: 3 freshquiz User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 36 m 29 sec
Reputation Power: 0
Prevent Infinite Recursion

Hi guys,

I have come across an extremely annoying problem in Postgresql.

I am trying to use this trigger:

Code:
CREATE FUNCTION next_calibration() RETURNS trigger AS $next_calibration$
    BEGIN
       IF TG_WHEN = 'AFTER' THEN

          IF TG_OP = 'INSERT' THEN

             UPDATE mi_calib_equip SET next_calib_date = last_calib_date + interval '6 months';

          ELSIF TG_OP = 'UPDATE' THEN

             UPDATE mi_calib_equip SET next_calib_date = last_calib_date + interval '6 months';
             
          END IF;
       END IF;
       RETURN NEW;
    END;
$next_calibration$ LANGUAGE plpgsql;

CREATE TRIGGER next_calibration AFTER INSERT OR UPDATE ON mi_calib_equip
EXECUTE PROCEDURE next_calibration();


I know the SQL in the trigger works fine because it runs perfectly on its own, but when I run it in this trigger, I get a stack error (pretty sure it is infinite recursion).
I'm pretty sure the problem is that I am using an UPDATE SQL statement in my trigger which is for some stupid reason, firing the function over and over.
Why is this so? I could understand if I was calling the function over and over, but this slight cross of UPDATE in the SQL statement and trigger is causing recursion. That is really stupid in my opinion.

Does anyone know of a way to overcome this problem?
I cannot use BEFORE UPDATE and NEW. because I need the update value (last_calib_date) from the user after it has been input.

Any help would be much appreciated. Thanks guys.

Reply With Quote
  #2  
Old January 9th, 2012, 01:38 AM
shammat shammat is offline
Contributing User
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: Oct 2003
Location: Germany
Posts: 2,506 shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 5 Days 2 h 54 m 8 sec
Reputation Power: 283
Quote:
Why is this so?
Because if a trigger is defined every UPDATE must fire that trigger. Otherwise the trigger doesn't make sense.

Quote:
I cannot use BEFORE UPDATE and NEW.
That's the only way to solve this.

Quote:
because I need the update value (last_calib_date) from the user after it has been input.
What do you mean with "after it has been input"? Any data that is sent to the database is "after the user has put it in". Where is the last_calib_date calculated?

Last edited by shammat : January 9th, 2012 at 01:42 AM.

Reply With Quote
  #3  
Old January 9th, 2012, 04:11 PM
freshquiz freshquiz is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2012
Posts: 3 freshquiz User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 36 m 29 sec
Reputation Power: 0
Ok, well that is annoying.

Sorry I will try to make it clearer.

last_calib_date will be changed by the user. I want the trigger (or whatever else will do this) to fire AFTER the record has been saved, in order to collect that latest value of last_calib_date that the user just changed to. I don't want the previous one, I wan't the latest one, hence if I use BEFORE I can't get the new can I?

Reply With Quote
  #4  
Old January 9th, 2012, 04:18 PM
freshquiz freshquiz is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2012
Posts: 3 freshquiz User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 36 m 29 sec
Reputation Power: 0
Ahhh forgive me shammat, you were on the money.

I had tried BEFORE and NEW. before, but for some it had not worked, but now it works perfectly.

Thanks shammat !

So this is my working code:

Code:
CREATE FUNCTION next_calibration() RETURNS trigger AS $next_calibration$
    BEGIN
       IF TG_WHEN = 'BEFORE' THEN

          IF TG_OP = 'INSERT' THEN

             NEW.next_calib_date = NEW.last_calib_date + interval '6 months';

          ELSIF TG_OP = 'UPDATE' THEN

             NEW.next_calib_date = NEW.last_calib_date + interval '6 months';
             
          END IF;
       
       END IF;
       RETURN NEW;
    END;
$next_calibration$ LANGUAGE plpgsql;

CREATE TRIGGER next_calibration BEFORE INSERT OR UPDATE ON mi_calib_equip
FOR EACH ROW
EXECUTE PROCEDURE next_calibration();

Reply With Quote
  #5  
Old January 9th, 2012, 04:22 PM
shammat shammat is offline
Contributing User
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: Oct 2003
Location: Germany
Posts: 2,506 shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level)shammat User rank is Captain (20000 - 30000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 5 Days 2 h 54 m 8 sec
Reputation Power: 283
Quote:
Originally Posted by freshquiz
hence if I use BEFORE I can't get the new can I?
Yes you can get it. That's what the "new" and "old" records are supplied for in a trigger function. And both are available in a BEFORE trigger.

In your case the "user supplied" (new) value will be available in new.last_calib_date and the previous (old) value would be available in old.last_calib_date

All you need to do, is to use it in an assignment:
Code:
CREATE FUNCTION next_calibration() RETURNS trigger AS $next_calibration$
    BEGIN
       new.next_calib_date = new.last_calib_date + interval '6 months';
       RETURN NEW;
    END;
$next_calibration$ LANGUAGE plpgsql;

CREATE TRIGGER next_calibration BEFORE INSERT OR UPDATE ON mi_calib_equip
EXECUTE PROCEDURE next_calibration();
As the trigger is defined as "BEFORE" there is also no need to check the TG_WHEN. That would only be necessary if you use the same trigger function for a BEFORE and an AFTER trigger.

Reply With Quote
Reply

Viewing: Dev Shed ForumsDatabasesPostgreSQL Help > Prevent Infinite Recursion


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.

© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 3 - Follow our Sitemap