Thread: Trigger and Trigger function.

Trigger and Trigger function.

From
Matt Iskra
Date:
Howdy y'all.

I have been trying to get a trigger and trigger function working. I have looked at the docs, copied the examples, and I
stillcannot get this to work. So, now I try you guys/gals. 

My test environment:
  Windows XP Pro (on my laptop)
  User account Postgre, with non-admin premissions
  PostgreSQL 8.0.3 (via msi)
  Installed the pl/pgsql language

I created a test database, named testdb. I created a schema called oc along with its own tablespace. The table creates
OK,but the function that is going to be called by the trigger gets a syntex error on the second line, where the
functionis named. 

My purpose is to get the last_touch field in the table to always have the timestamp when the record was inserted or
updated.

Thanks for the use of your expertise. Source code follows.

--Matthe

/****************************************/

CREATE TABLE oc.optical
(
    id serial NOT NULL,
    created timestamp NOT NULL DEFAULT ('now'::text)::timestamp(6) with time zone,
    last_touch timestamp NOT NULL DEFAULT ('now'::text)::timestamp(6) with time zone,
    file varchar(30),
    CONSTRAINT optical_pk PRIMARY KEY (id) USING INDEX TABLESPACE oc
)
WITHOUT OIDS TABLESPACE oc;
ALTER TABLE oc.optical OWNER TO oc;

CREATE FUNCTION
oc.upd_last_touch()      <-- syntex error here
RETURNS TRIGGER AS
$upd_last_touch$
BEGIN
    IF TG_NAME = 'optical_trig' THEN
        UPDATE optical
        SET NEW.last_touch = current_timestamp
        WHERE NEW.id = id;
    END IF;
END;
$upd_last_touch$
LANGUAGE 'plpgsql' VOLATILE;

ALTER FUNCTION oc.optical_upd() OWNER TO oc;

CREATE TRIGGER optical_trig BEFORE UPDATE ON optical
FOR EACH ROW EXECUTE PROCEDURE upd_last_touch();

/****************************************/




CONFIDENTIALITY NOTICE: This communication with its contents may contain
confidential and/or legally privileged information. It is solely for the
use of the intended recipient(s). Unauthorized interception, review, use
or disclosure is prohibited and may violate applicable laws including
the Electronic Communications Privacy Act. If you are not the intended
recipient, please contact the sender and destroy all copies of the
communication.

Re: Trigger and Trigger function.

From
John DeSoi
Date:
On Jun 16, 2005, at 6:56 PM, Matt Iskra wrote:

> CREATE FUNCTION
> oc.upd_last_touch()      <-- syntex error here
> RETURNS TRIGGER AS
> $upd_last_touch$
> BEGIN
>     IF TG_NAME = 'optical_trig' THEN
>         UPDATE optical
>         SET NEW.last_touch = current_timestamp
>         WHERE NEW.id = id;
>     END IF;
> END;
> $upd_last_touch$
> LANGUAGE 'plpgsql' VOLATILE;


I don't think $upd_last_touch$ is a legal dollar quote. It needs to be
alphanumeric characters only (no underscores).


John DeSoi, Ph.D.
http://pgedit.com/
Power Tools for PostgreSQL


Re: Trigger and Trigger function.

From
Michael Fuhr
Date:
On Fri, Jun 17, 2005 at 07:55:36AM -0400, John DeSoi wrote:
> On Jun 16, 2005, at 6:56 PM, Matt Iskra wrote:
>
> >CREATE FUNCTION
> >oc.upd_last_touch()      <-- syntex error here
> >RETURNS TRIGGER AS
> >$upd_last_touch$
> >BEGIN
> >    IF TG_NAME = 'optical_trig' THEN
> >        UPDATE optical
> >        SET NEW.last_touch = current_timestamp
> >        WHERE NEW.id = id;
> >    END IF;
> >END;
> >$upd_last_touch$
> >LANGUAGE 'plpgsql' VOLATILE;
>
> I don't think $upd_last_touch$ is a legal dollar quote. It needs to be
> alphanumeric characters only (no underscores).

Eh?  Works here in 8.0.3, at least in psql:

test=> CREATE FUNCTION foo() RETURNS integer AS $upd_last_touch$
test$> BEGIN
test$>     RETURN 12345;
test$> END;
test$> $upd_last_touch$ LANGUAGE plpgsql;
CREATE FUNCTION
test=> SELECT foo();
  foo
-------
 12345
(1 row)

Matt, what's telling you where the error is and what exactly is the
error?  I see a few things wrong with what you posted:

1. You create a function named oc.upd_last_touch() and subsequently
issue an ALTER FUNCTION statement for oc.optical_upd(), a different
function.  Is that correct?  You don't show the latter being created.

2. You've created the table oc.optical but the CREATE TRIGGER
statement refers to just optical without a schema qualifier;
likewise with the function upd_last_touch().  Do you have oc
in your search_path?

If I correct the above two problems then the code you posted
successfully loads in my test database (after creating the schema,
tablespace, and user).  However, inserting a record into the table
and then updating that record gives the following error:

ERROR:  syntax error at or near "$1" at character 21
QUERY:  UPDATE optical SET  $1  = current_timestamp WHERE  $2  = id
CONTEXT:  PL/pgSQL function "upd_last_touch" line 3 at SQL statement
LINE 1: UPDATE optical SET  $1  = current_timestamp WHERE  $2  = id

Instead of doing an UPDATE in the trigger function, you should be
modifying NEW and returning it, like this:

CREATE OR REPLACE FUNCTION oc.upd_last_touch() RETURNS trigger
AS $upd_last_touch$
BEGIN
    NEW.last_touch := current_timestamp;
    RETURN NEW;
END;
$upd_last_touch$ LANGUAGE plpgsql;

See the "Triggers" chapter in the documentation and the "Trigger
Procedures" section in the PL/pgSQL chapter for more info:

http://www.postgresql.org/docs/8.0/static/triggers.html
http://www.postgresql.org/docs/8.0/static/plpgsql-trigger.html

--
Michael Fuhr
http://www.fuhr.org/~mfuhr/

Re: Trigger and Trigger function.

From
John DeSoi
Date:
On Jun 17, 2005, at 8:59 AM, Michael Fuhr wrote:

>> I don't think $upd_last_touch$ is a legal dollar quote. It needs to be
>> alphanumeric characters only (no underscores).
>
> Eh?  Works here in 8.0.3, at least in psql:


Hmm, sorry I don't know what I did the first time. I pasted the code
(removing the annotation) and executed it. I got an "unterminated
dollar quote" error. I changed them to '$$' and then it worked. I must
have had some other stray change that I missed.

For the record, here is the dollar quote format - alphanumeric plus
underscore.


dolq_start        [A-Za-z\200-\377_]
dolq_cont        [A-Za-z\200-\377_0-9]
dolqdelim        \$({dolq_start}{dolq_cont}*)?\$
dolqinside        [^$]+


John DeSoi, Ph.D.
http://pgedit.com/
Power Tools for PostgreSQL