29 Jan 2009

Postgresql and the trigger of death

Description of the problem:
I have a table with 2 columns date_acq and time_acq as text

CREATE TABLE "shapefiles" (gid serial PRIMARY KEY,
"date_acq varchar(10),
"time_acq" varchar(8));


I want a colum with a datetime time with the informations from date_acq and time_acq so that I can use the < and > sql operator.


I added a new column datetime_acq of type datetime and a trigger getting the information from date_acq and time_acq and putting them into the new column.
The trick is that the date is express in french format that is DD/MM/YYYY.


After learning and fighting with postgres stored procedure language I finally got a nice looking solution:

BEGIN;
ALTER TABLE shapefiles DROP COLUMN datetime_acq;
ALTER TABLE shapefiles ADD COLUMN datetime_acq timestamp with time zone;
COMMIT;

DROP FUNCTION IF EXISTS datetime_acq_timestamp() CASCADE;
CREATE FUNCTION datetime_acq_timestamp() RETURNS trigger AS $datetime_acq_timestamp$
DECLARE
temp_date text;
french_pattern text := 'DD/MM/YYYY';
BEGIN
-- Check that date_acq and time_acq are given
IF NEW.date_acq IS NULL THEN
RAISE EXCEPTION 'date_acq cannot be null';
END IF;
IF NEW.time_acq IS NULL THEN
RAISE EXCEPTION 'time_acq cannot be null';
END IF;

-- Updating datetime_acq column
SELECT TO_CHAR(TO_DATE(NEW.date_acq,french_pattern), 'YYYY-MM-DD') into temp_date;
NEW.datetime_acq := temp_date || ' ' || NEW.time_acq;
RETURN NEW;
END;
$datetime_acq_timestamp$ LANGUAGE plpgsql;

CREATE TRIGGER datetime_acq_trigger BEFORE INSERT OR UPDATE ON shapefiles
FOR EACH ROW EXECUTE PROCEDURE datetime_acq_timestamp();

"Et voilĂ !" Now I have a nice column with valuable informations:

No comments: