I have the following update trigger for a tsvector column
CREATE TRIGGER tsvector_user_update
BEFORE INSERT OR UPDATE ON users
FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger(user_tsv, 'pg_catalog.english', firstname, surname, email, card_id);
This works fine, however my card_id column (text) contains a pre-amble that the user is not aware of (it is added after the card is scanned), so I would like to strip out the pre-amble when the tsvector value is generated, I have tried the trigger function as a start
CREATE FUNCTION user_change_trigger() RETURNS trigger AS $$
BEGIN
NEW.user_tsv = setweight(to_tsvector('pg_catalog.english', coalesce(NEW.firstname,'')), 'A') ||
setweight(to_tsvector('pg_catalog.english', coalesce(NEW.surname,'')), 'A') ||
setweight(to_tsvector('pg_catalog.english', coalesce(REGEXP_REPLACE(NEW.card_id, '^\d+PRE', ''),'')), 'B') ||
setweight(to_tsvector('pg_catalog.english', coalesce(NEW.email,'')), 'C');
return new;
END
$$ LANGUAGE plpgsql;
CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
ON users FOR EACH ROW EXECUTE PROCEDURE user_change_trigger();
Which executes, but I get the following:
WARNING: nonstandard use of escape in a string literal
And no updated tsvector
The pre-amble is an integer followed by 'PRE'.
(PostgreSQL 9.0)
The problem is of principal nature. In PostgreSQL you create a trigger function that does the work. I don't see your trigger function in the question.
Then you create a trigger which makes use of this function. You can only pass constants to a trigger function. Consider this quote from the manual about CREATE TRIGGER
function_name
A user-supplied function that is declared as taking no arguments and returning type trigger, which is executed when the trigger fires.
arguments
An optional comma-separated list of arguments to be provided to the function when the trigger is executed. The arguments are literal string constants . Simple names and numeric constants can be written here, too, but they will all be converted to strings. Please check the description of the implementation language of the trigger function to find out how these arguments can be accessed within the function; it might be different from normal function arguments.
Bold emphasis mine.
Use NEW
to access the column values inside the trigger function. You don't need to pass them as arguments. Get a grip on the basic concept first. Start here.
regexp_replace()
Use:
regexp_replace(card_id, '^\d+PRE', '')
.. since the leading characters are supposed to be digits only (and at least one of them).
The following test case works for me on PostgreSQL 9.1.6. Your version looks basically good to me, I only made minor changes. But keep reading ...
Create test environment (will be rolled back at the end):
BEGIN;
CREATE SCHEMA test;
SET search_path = test;
CREATE TABLE users (
users_id serial primary key
,firstname text
,surname text
,card_id text
,email text
,user_tsv tsvector
);
Trigger function:
CREATE FUNCTION user_change_trigger()
RETURNS trigger AS
$func$
BEGIN
NEW.user_tsv :=
setweight(to_tsvector('pg_catalog.english', coalesce(NEW.firstname,'')), 'A')
|| setweight(to_tsvector('pg_catalog.english', coalesce(NEW.surname,'')), 'A')
|| setweight(to_tsvector('pg_catalog.english', coalesce(regexp_replace(NEW.card_id, '^\d+PRE', ''),'')), 'B')
|| setweight(to_tsvector('pg_catalog.english', coalesce(NEW.email,'')), 'C');
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
The assignment operator of plpgsql is :=
- unlike SQL where =
is used.
Trigger:
CREATE TRIGGER tsvectorupdate
BEFORE INSERT OR UPDATE ON users
FOR EACH ROW EXECUTE PROCEDURE user_change_trigger();
Tests:
INSERT INTO users (firstname, surname, card_id, email)
VALUES ('Erwin', 'Brandstetter', '123PRE456', 'foo@dummy.org')
RETURNING *;
-- looks good!
UPDATE users SET firstname = 'Walter' WHERE TRUE
RETURNING *;
-- looks good, too!
Clean up:
ROLLBACK;
standard_conforming_strings
Explore your setting of standard_conforming_strings
. The WARNING suggests that you don't have this setting on, which would require that you double the backslash in:
'^\\d+PRE'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.