Stored procedure - change columns in a table that is being updated / inserted on? - Mailing list pgsql-novice

From bryan@flyingiranch.com
Subject Stored procedure - change columns in a table that is being updated / inserted on?
Date
Msg-id H00000660001d077.1047163275.mule.flyingiranch.com@MHS
Whole thread Raw
Responses Re: Stored procedure - change columns in a table that is being updated / inserted on?
List pgsql-novice
Greetings:

I am working on a health maintenance application in which I have some
calculations to derive things like body mass index (which is a static
value based on a person's weight and height). I hit my head against a
wall for a full day trying to do this with a stored procedure like:
---------------------------------------------
CREATE FUNCTION calcbmi() RETURNS trigger AS '
  DECLARE
    userrow RECORD;
    userbmi FLOAT;
    tempid INT;
  BEGIN
    SELECT INTO userrow * FROM tbluserhealthbasic WHERE userID =
NEW.userID;

    IF NOT FOUND THEN
      RAISE EXCEPTION ''Invalid User ID!'';
    END IF;

      userbmi := (userrow.userWeight / (userrow.userHeight *
userrow.userHeight));
      UPDATE tbluserhealthbasic SET bmi=userbmi WHERE userID =
NEW.userID;
    END IF;

    RETURN NEW;
  END;
' LANGUAGE 'plpgsql';

CREATE TRIGGER docalcbmi AFTER INSERT OR UPDATE
  ON tblUserHealthBasic FOR EACH ROW EXECUTE
  PROCEDURE calcbmi();
---------------------------------------------

The problem with this, as I now know, is that any insert or update query
to that table would hang on the update statement, as the row is of
course locked at the time. Once I moved the calculated values to a
separate table, everything works fine, with the following changes to the
function:
---------------------------------------------
CREATE FUNCTION calcbmi() RETURNS trigger AS '
  DECLARE
    userrow RECORD;
    userbmi FLOAT;
    tempid INT;
  BEGIN
    SELECT INTO userrow * FROM tbluserhealthbasic WHERE userID =
NEW.userID;

    IF NOT FOUND THEN
      RAISE EXCEPTION ''Invalid User ID!'';
    END IF;

    userbmi := (userrow.userWeight / (userrow.userHeight *
userrow.userHeight));

    -- We need to determine whether to insert or update
    SELECT INTO tempid userID FROM tblUserHealthCalculated where userID
= NEW.userID;
    IF NOT FOUND THEN
      INSERT INTO tbluserHealthCalculated (userID, bmi) values
(NEW.userID, userbmi);
    ELSE
      UPDATE tbluserhealthcalculated SET bmi=userbmi WHERE userID =
NEW.userID;
    END IF;

    RETURN NEW;
  END;
' LANGUAGE 'plpgsql';
---------------------------------------------

As you can see, I created a new table, tbluserhealthcalculated, that is
actually written to on any insert or update to tbluserhealthbasic.

What I want to know: Is there a way around the locking issue, so I can
use a trigger to update columns in the same table that is being written
to?

Thanks,

Bryan

---x-----x-----x-----x-----x---
Bryan White of Flying I Ranch
Technology Wrangler
bryan@flyingiranch.com
http://www.flyingiranch.com
(503) 777-2895



Attachment

pgsql-novice by date:

Previous
From: Luis Miedzinski
Date:
Subject: best php coding practices
Next
From: Tom Lane
Date:
Subject: Re: Stored procedure - change columns in a table that is being updated / inserted on?