Search Postgresql Archives

Function to determine next payment date

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I'm trying to create a function to determine the next due payment date of a recurring expense.

I have a table containing the date the payment first started, and a payment frequency key which relates to a payment ID in another table containing a string defining how frequent the payment exists.

-- Cut down version of table definitions:

CREATE TABLE "tblRecuringExpenses"
(
  expense_id integer NOT NULL DEFAULT nextval('seq_expense_id'::regclass),
  expense_frequency character varying(1) NOT NULL,
  expense_startdate timestamp with time zone NOT NULL,
  CONSTRAINT pk_tblrecuringexpenses_expense_id PRIMARY KEY (expense_id),
CONSTRAINT fk_tblrecuringexpenses_expense_frequency FOREIGN KEY (expense_frequency)
      REFERENCES "tblRecuringFrequency" (frequency_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITHOUT OIDS;

CREATE TABLE "tblRecuringFrequency"
(
  frequency_id character varying(1) NOT NULL,
  next_payment character varying(40),
  CONSTRAINT pk_tblrecuringfrequency_frequncy_id PRIMARY KEY (frequency_id)
)
WITHOUT OIDS;


I figure the best way to get the next payment date is to create a function that takes in the payment ID, then loops through adding the payment frequency interval onto the start date until it gets to a date that's greater than or equal to the current date.

Firstly... is this assumption correct or is there an easier way to do it?

Secondly... assuming my initial assumption is correct I've created the following function in PL/pgSQL, however when I execute it, it runs for minutes - where the two tables above I'm working with are dummy test tables that contain 2 rows each and the calculations are simple enough that I would assume a speedy conclusion - it would seem to me that my loop is endless.

An explain analyze does me no good - that get's stuck in the same endless loop, and a simple explain only gives me:
 "Result  (cost=0.00..0.01 rows=1 width=0)"


CREATE OR REPLACE FUNCTION fnNextPaymentDue(integer) RETURNS timestamp AS $$
DECLARE
   start_date timestamp;
   next_payment interval;
   loop_count int;
BEGIN
   SELECT INTO start_date (SELECT expense_startdate FROM
      "tblRecuringExpenses" WHERE expense_id=$1);
   SELECT INTO next_payment (select next_payment from
      "tblRecuringFrequency" JOIN "tblRecuringExpenses" on
      ("tblRecuringFrequency".frequency_id
       ="tblRecuringExpenses".expense_frequency)
      WHERE expense_id=$1)::interval;
LOOP
   if start_date >=current_date then
      exit;
   end if;
   start_date:=start_date+next_payment;
END LOOP;
RETURN start_date;
END;
$$ LANGUAGE PLPGSQL STABLE;

Since it's my first function in PL/pgSQL I've probably missed something pretty obvious - but if someone could point it out to me that would be muchly appreciated.

--
Paul Lambert
Database Administrator
AutoLedgers


---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux